Here are the main MIPS updates for 4.20:
- kexec support for the generic MIPS platform when running on a CPU including the MIPS Coherence Manager & related hardware. - Improvements to the definition of memory barriers used around MMIO accesses, and fixes in their use. - Switch to CONFIG_NO_BOOTMEM from Mike Rapoport, finally dropping reliance on the old bootmem code. - A number of fixes & improvements for Loongson 3 systems. - DT & config updates for the Microsemi Ocelot platform. - Workaround to enable USB power on the Netgear WNDR3400v3. - Various cleanups & fixes. -----BEGIN PGP SIGNATURE----- iIsEABYIADMWIQRgLjeFAZEXQzy86/s+p5+stXUA3QUCW9NfwRUccGF1bC5idXJ0 b25AbWlwcy5jb20ACgkQPqefrLV1AN1LNgD9Hy73DkYnnYeLNLcCe+5QMCr+NO2C kwIs7kAI40X+/LQA/RgCcg6z4rUSH38hfNEobD6VXva7QiFhiYcJj5rCFH8O =nDQg -----END PGP SIGNATURE----- Merge tag 'mips_4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux Pull MIPS updates from Paul Burton: - kexec support for the generic MIPS platform when running on a CPU including the MIPS Coherence Manager & related hardware. - Improvements to the definition of memory barriers used around MMIO accesses, and fixes in their use. - Switch to CONFIG_NO_BOOTMEM from Mike Rapoport, finally dropping reliance on the old bootmem code. - A number of fixes & improvements for Loongson 3 systems. - DT & config updates for the Microsemi Ocelot platform. - Workaround to enable USB power on the Netgear WNDR3400v3. - Various cleanups & fixes. * tag 'mips_4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (51 commits) MIPS: Cleanup DSP ASE detection MIPS: dts: Change upper case to lower case MIPS: generic: Add Network, SPI and I2C to ocelot_defconfig MIPS: Loongson-3: Fix BRIDGE irq delivery problem MIPS: Loongson-3: Fix CPU UART irq delivery problem MIPS: Remove unused PREF, PREFE & PREFX macros MIPS: lib: Use kernel_pref & user_pref in memcpy() MIPS: Remove unused CAT macro MIPS: Add kernel_pref & user_pref helpers MIPS: Remove unused TTABLE macro MIPS: Remove unused PIC macros MIPS: Remove unused MOVN & MOVZ macros MIPS: Provide actually relaxed MMIO accessors MIPS: Enforce strong ordering for MMIO accessors MIPS: Correct `mmiowb' barrier for `wbflush' platforms MIPS: Define MMIO ordering barriers MIPS: mscc: add PCB120 to the ocelot fitImage MIPS: mscc: add DT for Ocelot PCB120 MIPS: memset: Limit excessive `noreorder' assembly mode use MIPS: memset: Fix CPU_DADDI_WORKAROUNDS `small_fixup' regression ...
This commit is contained in:
commit
cc10ad25bb
|
@ -21,6 +21,7 @@ config MIPS
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
select GENERIC_CMOS_UPDATE
|
select GENERIC_CMOS_UPDATE
|
||||||
select GENERIC_CPU_AUTOPROBE
|
select GENERIC_CPU_AUTOPROBE
|
||||||
|
select GENERIC_IOMAP
|
||||||
select GENERIC_IRQ_PROBE
|
select GENERIC_IRQ_PROBE
|
||||||
select GENERIC_IRQ_SHOW
|
select GENERIC_IRQ_SHOW
|
||||||
select GENERIC_LIB_ASHLDI3
|
select GENERIC_LIB_ASHLDI3
|
||||||
|
@ -28,7 +29,6 @@ config MIPS
|
||||||
select GENERIC_LIB_CMPDI2
|
select GENERIC_LIB_CMPDI2
|
||||||
select GENERIC_LIB_LSHRDI3
|
select GENERIC_LIB_LSHRDI3
|
||||||
select GENERIC_LIB_UCMPDI2
|
select GENERIC_LIB_UCMPDI2
|
||||||
select GENERIC_PCI_IOMAP
|
|
||||||
select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
|
select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
|
@ -78,6 +78,7 @@ config MIPS
|
||||||
select RTC_LIB if !MACH_LOONGSON64
|
select RTC_LIB if !MACH_LOONGSON64
|
||||||
select SYSCTL_EXCEPTION_TRACE
|
select SYSCTL_EXCEPTION_TRACE
|
||||||
select VIRT_TO_BUS
|
select VIRT_TO_BUS
|
||||||
|
select NO_BOOTMEM
|
||||||
|
|
||||||
menu "Machine selection"
|
menu "Machine selection"
|
||||||
|
|
||||||
|
@ -132,6 +133,7 @@ config MIPS_GENERIC
|
||||||
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||||
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||||
select USE_OF
|
select USE_OF
|
||||||
|
select UHI_BOOT
|
||||||
help
|
help
|
||||||
Select this to build a kernel which aims to support multiple boards,
|
Select this to build a kernel which aims to support multiple boards,
|
||||||
generally using a flattened device tree passed from the bootloader
|
generally using a flattened device tree passed from the bootloader
|
||||||
|
@ -1149,6 +1151,7 @@ config NO_IOPORT_MAP
|
||||||
|
|
||||||
config GENERIC_CSUM
|
config GENERIC_CSUM
|
||||||
bool
|
bool
|
||||||
|
default y if !CPU_HAS_LOAD_STORE_LR
|
||||||
|
|
||||||
config GENERIC_ISA_DMA
|
config GENERIC_ISA_DMA
|
||||||
bool
|
bool
|
||||||
|
@ -1367,6 +1370,7 @@ config CPU_LOONGSON3
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select WEAK_ORDERING
|
select WEAK_ORDERING
|
||||||
select WEAK_REORDERING_BEYOND_LLSC
|
select WEAK_REORDERING_BEYOND_LLSC
|
||||||
select MIPS_PGD_C0_CONTEXT
|
select MIPS_PGD_C0_CONTEXT
|
||||||
|
@ -1443,6 +1447,7 @@ config CPU_MIPS32_R1
|
||||||
bool "MIPS32 Release 1"
|
bool "MIPS32 Release 1"
|
||||||
depends on SYS_HAS_CPU_MIPS32_R1
|
depends on SYS_HAS_CPU_MIPS32_R1
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
help
|
help
|
||||||
|
@ -1460,6 +1465,7 @@ config CPU_MIPS32_R2
|
||||||
bool "MIPS32 Release 2"
|
bool "MIPS32 Release 2"
|
||||||
depends on SYS_HAS_CPU_MIPS32_R2
|
depends on SYS_HAS_CPU_MIPS32_R2
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_MSA
|
select CPU_SUPPORTS_MSA
|
||||||
|
@ -1478,7 +1484,6 @@ config CPU_MIPS32_R6
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_MSA
|
select CPU_SUPPORTS_MSA
|
||||||
select GENERIC_CSUM
|
|
||||||
select HAVE_KVM
|
select HAVE_KVM
|
||||||
select MIPS_O32_FP64_SUPPORT
|
select MIPS_O32_FP64_SUPPORT
|
||||||
help
|
help
|
||||||
|
@ -1491,6 +1496,7 @@ config CPU_MIPS64_R1
|
||||||
bool "MIPS64 Release 1"
|
bool "MIPS64 Release 1"
|
||||||
depends on SYS_HAS_CPU_MIPS64_R1
|
depends on SYS_HAS_CPU_MIPS64_R1
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1510,6 +1516,7 @@ config CPU_MIPS64_R2
|
||||||
bool "MIPS64 Release 2"
|
bool "MIPS64 Release 2"
|
||||||
depends on SYS_HAS_CPU_MIPS64_R2
|
depends on SYS_HAS_CPU_MIPS64_R2
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1531,7 +1538,6 @@ config CPU_MIPS64_R6
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_MSA
|
select CPU_SUPPORTS_MSA
|
||||||
select GENERIC_CSUM
|
|
||||||
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
|
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
|
||||||
select HAVE_KVM
|
select HAVE_KVM
|
||||||
help
|
help
|
||||||
|
@ -1544,6 +1550,7 @@ config CPU_R3000
|
||||||
bool "R3000"
|
bool "R3000"
|
||||||
depends on SYS_HAS_CPU_R3000
|
depends on SYS_HAS_CPU_R3000
|
||||||
select CPU_HAS_WB
|
select CPU_HAS_WB
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
help
|
help
|
||||||
|
@ -1558,12 +1565,14 @@ config CPU_TX39XX
|
||||||
bool "R39XX"
|
bool "R39XX"
|
||||||
depends on SYS_HAS_CPU_TX39XX
|
depends on SYS_HAS_CPU_TX39XX
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
|
|
||||||
config CPU_VR41XX
|
config CPU_VR41XX
|
||||||
bool "R41xx"
|
bool "R41xx"
|
||||||
depends on SYS_HAS_CPU_VR41XX
|
depends on SYS_HAS_CPU_VR41XX
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
The options selects support for the NEC VR4100 series of processors.
|
The options selects support for the NEC VR4100 series of processors.
|
||||||
Only choose this option if you have one of these processors as a
|
Only choose this option if you have one of these processors as a
|
||||||
|
@ -1575,6 +1584,7 @@ config CPU_R4300
|
||||||
depends on SYS_HAS_CPU_R4300
|
depends on SYS_HAS_CPU_R4300
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
MIPS Technologies R4300-series processors.
|
MIPS Technologies R4300-series processors.
|
||||||
|
|
||||||
|
@ -1584,6 +1594,7 @@ config CPU_R4X00
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
MIPS Technologies R4000-series processors other than 4300, including
|
MIPS Technologies R4000-series processors other than 4300, including
|
||||||
the R4000, R4400, R4600, and 4700.
|
the R4000, R4400, R4600, and 4700.
|
||||||
|
@ -1592,6 +1603,7 @@ config CPU_TX49XX
|
||||||
bool "R49XX"
|
bool "R49XX"
|
||||||
depends on SYS_HAS_CPU_TX49XX
|
depends on SYS_HAS_CPU_TX49XX
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
@ -1602,6 +1614,7 @@ config CPU_R5000
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
MIPS Technologies R5000-series processors other than the Nevada.
|
MIPS Technologies R5000-series processors other than the Nevada.
|
||||||
|
|
||||||
|
@ -1611,6 +1624,7 @@ config CPU_R5432
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
|
|
||||||
config CPU_R5500
|
config CPU_R5500
|
||||||
bool "R5500"
|
bool "R5500"
|
||||||
|
@ -1618,6 +1632,7 @@ config CPU_R5500
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
|
NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
|
||||||
instruction set.
|
instruction set.
|
||||||
|
@ -1628,6 +1643,7 @@ config CPU_NEVADA
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
help
|
help
|
||||||
QED / PMC-Sierra RM52xx-series ("Nevada") processors.
|
QED / PMC-Sierra RM52xx-series ("Nevada") processors.
|
||||||
|
|
||||||
|
@ -1635,6 +1651,7 @@ config CPU_R8000
|
||||||
bool "R8000"
|
bool "R8000"
|
||||||
depends on SYS_HAS_CPU_R8000
|
depends on SYS_HAS_CPU_R8000
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
help
|
help
|
||||||
MIPS Technologies R8000 processors. Note these processors are
|
MIPS Technologies R8000 processors. Note these processors are
|
||||||
|
@ -1644,6 +1661,7 @@ config CPU_R10000
|
||||||
bool "R10000"
|
bool "R10000"
|
||||||
depends on SYS_HAS_CPU_R10000
|
depends on SYS_HAS_CPU_R10000
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1655,6 +1673,7 @@ config CPU_RM7000
|
||||||
bool "RM7000"
|
bool "RM7000"
|
||||||
depends on SYS_HAS_CPU_RM7000
|
depends on SYS_HAS_CPU_RM7000
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1663,6 +1682,7 @@ config CPU_RM7000
|
||||||
config CPU_SB1
|
config CPU_SB1
|
||||||
bool "SB1"
|
bool "SB1"
|
||||||
depends on SYS_HAS_CPU_SB1
|
depends on SYS_HAS_CPU_SB1
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1673,6 +1693,7 @@ config CPU_CAVIUM_OCTEON
|
||||||
bool "Cavium Octeon processor"
|
bool "Cavium Octeon processor"
|
||||||
depends on SYS_HAS_CPU_CAVIUM_OCTEON
|
depends on SYS_HAS_CPU_CAVIUM_OCTEON
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select WEAK_ORDERING
|
select WEAK_ORDERING
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1702,6 +1723,7 @@ config CPU_BMIPS
|
||||||
select WEAK_ORDERING
|
select WEAK_ORDERING
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_CPUFREQ
|
select CPU_SUPPORTS_CPUFREQ
|
||||||
select MIPS_EXTERNAL_TIMER
|
select MIPS_EXTERNAL_TIMER
|
||||||
help
|
help
|
||||||
|
@ -1710,6 +1732,7 @@ config CPU_BMIPS
|
||||||
config CPU_XLR
|
config CPU_XLR
|
||||||
bool "Netlogic XLR SoC"
|
bool "Netlogic XLR SoC"
|
||||||
depends on SYS_HAS_CPU_XLR
|
depends on SYS_HAS_CPU_XLR
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_64BIT_KERNEL
|
select CPU_SUPPORTS_64BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
|
@ -1728,6 +1751,7 @@ config CPU_XLP
|
||||||
select WEAK_ORDERING
|
select WEAK_ORDERING
|
||||||
select WEAK_REORDERING_BEYOND_LLSC
|
select WEAK_REORDERING_BEYOND_LLSC
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_MIPSR2
|
select CPU_MIPSR2
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
select MIPS_ASID_BITS_VARIABLE
|
select MIPS_ASID_BITS_VARIABLE
|
||||||
|
@ -1833,12 +1857,14 @@ config CPU_LOONGSON2
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_HUGEPAGES
|
select CPU_SUPPORTS_HUGEPAGES
|
||||||
select ARCH_HAS_PHYS_TO_DMA
|
select ARCH_HAS_PHYS_TO_DMA
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
|
|
||||||
config CPU_LOONGSON1
|
config CPU_LOONGSON1
|
||||||
bool
|
bool
|
||||||
select CPU_MIPS32
|
select CPU_MIPS32
|
||||||
select CPU_MIPSR1
|
select CPU_MIPSR1
|
||||||
select CPU_HAS_PREFETCH
|
select CPU_HAS_PREFETCH
|
||||||
|
select CPU_HAS_LOAD_STORE_LR
|
||||||
select CPU_SUPPORTS_32BIT_KERNEL
|
select CPU_SUPPORTS_32BIT_KERNEL
|
||||||
select CPU_SUPPORTS_HIGHMEM
|
select CPU_SUPPORTS_HIGHMEM
|
||||||
select CPU_SUPPORTS_CPUFREQ
|
select CPU_SUPPORTS_CPUFREQ
|
||||||
|
@ -2452,6 +2478,13 @@ config XKS01
|
||||||
config CPU_HAS_RIXI
|
config CPU_HAS_RIXI
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config CPU_HAS_LOAD_STORE_LR
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
CPU has support for unaligned load and store instructions:
|
||||||
|
LWL, LWR, SWL, SWR (Load/store word left/right).
|
||||||
|
LDL, LDR, SDL, SDR (Load/store doubleword left/right, for 64bit systems).
|
||||||
|
|
||||||
#
|
#
|
||||||
# Vectored interrupt mode is an R2 feature
|
# Vectored interrupt mode is an R2 feature
|
||||||
#
|
#
|
||||||
|
@ -2899,6 +2932,9 @@ config USE_OF
|
||||||
select OF_EARLY_FLATTREE
|
select OF_EARLY_FLATTREE
|
||||||
select IRQ_DOMAIN
|
select IRQ_DOMAIN
|
||||||
|
|
||||||
|
config UHI_BOOT
|
||||||
|
bool
|
||||||
|
|
||||||
config BUILTIN_DTB
|
config BUILTIN_DTB
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
archscripts: scripts_basic
|
archscripts: scripts_basic
|
||||||
|
$(Q)$(MAKE) $(build)=arch/mips/tools elf-entry
|
||||||
$(Q)$(MAKE) $(build)=arch/mips/boot/tools relocs
|
$(Q)$(MAKE) $(build)=arch/mips/boot/tools relocs
|
||||||
|
|
||||||
KBUILD_DEFCONFIG := 32r2el_defconfig
|
KBUILD_DEFCONFIG := 32r2el_defconfig
|
||||||
|
@ -230,6 +231,8 @@ toolchain-xpa := $(call cc-option-yn,$(xpa-cflags-y) -mxpa)
|
||||||
cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA
|
cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA
|
||||||
toolchain-crc := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mcrc)
|
toolchain-crc := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mcrc)
|
||||||
cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC
|
cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC
|
||||||
|
toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp)
|
||||||
|
cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP
|
||||||
|
|
||||||
#
|
#
|
||||||
# Firmware support
|
# Firmware support
|
||||||
|
@ -257,13 +260,7 @@ ifdef CONFIG_PHYSICAL_START
|
||||||
load-y = $(CONFIG_PHYSICAL_START)
|
load-y = $(CONFIG_PHYSICAL_START)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Sign-extend the entry point to 64 bits if retrieved as a 32-bit number.
|
entry-y = $(shell $(objtree)/arch/mips/tools/elf-entry vmlinux)
|
||||||
entry-y = $(shell $(OBJDUMP) -f vmlinux 2>/dev/null \
|
|
||||||
| sed -n '/^start address / { \
|
|
||||||
s/^.* //; \
|
|
||||||
s/0x\([0-7].......\)$$/0x00000000\1/; \
|
|
||||||
s/0x\(........\)$$/0xffffffff\1/; p }')
|
|
||||||
|
|
||||||
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
|
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
|
||||||
drivers-$(CONFIG_PCI) += arch/mips/pci/
|
drivers-$(CONFIG_PCI) += arch/mips/pci/
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
#include <bcm47xx_board.h>
|
#include <bcm47xx_board.h>
|
||||||
#include <bcm47xx.h>
|
#include <bcm47xx.h>
|
||||||
|
|
||||||
static void __init bcm47xx_workarounds_netgear_wnr3500l(void)
|
static void __init bcm47xx_workarounds_enable_usb_power(int usb_power)
|
||||||
{
|
{
|
||||||
const int usb_power = 12;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = gpio_request_one(usb_power, GPIOF_OUT_INIT_HIGH, "usb_power");
|
err = gpio_request_one(usb_power, GPIOF_OUT_INIT_HIGH, "usb_power");
|
||||||
|
@ -23,7 +22,10 @@ void __init bcm47xx_workarounds(void)
|
||||||
|
|
||||||
switch (board) {
|
switch (board) {
|
||||||
case BCM47XX_BOARD_NETGEAR_WNR3500L:
|
case BCM47XX_BOARD_NETGEAR_WNR3500L:
|
||||||
bcm47xx_workarounds_netgear_wnr3500l();
|
bcm47xx_workarounds_enable_usb_power(12);
|
||||||
|
break;
|
||||||
|
case BCM47XX_BOARD_NETGEAR_WNDR3400_V3:
|
||||||
|
bcm47xx_workarounds_enable_usb_power(21);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* No workaround(s) needed */
|
/* No workaround(s) needed */
|
||||||
|
|
|
@ -153,8 +153,6 @@ void __init plat_time_init(void)
|
||||||
mips_hpt_frequency = freq;
|
mips_hpt_frequency = freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char __appended_dtb;
|
|
||||||
|
|
||||||
void __init plat_mem_setup(void)
|
void __init plat_mem_setup(void)
|
||||||
{
|
{
|
||||||
void *dtb;
|
void *dtb;
|
||||||
|
@ -164,15 +162,10 @@ void __init plat_mem_setup(void)
|
||||||
ioport_resource.start = 0;
|
ioport_resource.start = 0;
|
||||||
ioport_resource.end = ~0;
|
ioport_resource.end = ~0;
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
|
|
||||||
if (!fdt_check_header(&__appended_dtb))
|
|
||||||
dtb = (void *)&__appended_dtb;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
/* intended to somewhat resemble ARM; see Documentation/arm/Booting */
|
/* intended to somewhat resemble ARM; see Documentation/arm/Booting */
|
||||||
if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
|
if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
|
||||||
dtb = phys_to_virt(fw_arg2);
|
dtb = phys_to_virt(fw_arg2);
|
||||||
else if (fw_passed_dtb) /* UHI interface */
|
else if (fw_passed_dtb) /* UHI interface or appended dtb */
|
||||||
dtb = (void *)fw_passed_dtb;
|
dtb = (void *)fw_passed_dtb;
|
||||||
else if (__dtb_start != __dtb_end)
|
else if (__dtb_start != __dtb_end)
|
||||||
dtb = (void *)__dtb_start;
|
dtb = (void *)__dtb_start;
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
biu@1F800000 {
|
biu@1f800000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "lantiq,biu", "simple-bus";
|
compatible = "lantiq,biu", "simple-bus";
|
||||||
reg = <0x1F800000 0x800000>;
|
reg = <0x1f800000 0x800000>;
|
||||||
ranges = <0x0 0x1F800000 0x7FFFFF>;
|
ranges = <0x0 0x1f800000 0x7fffff>;
|
||||||
|
|
||||||
icu0: icu@80200 {
|
icu0: icu@80200 {
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
|
@ -24,18 +24,18 @@
|
||||||
reg = <0x80200 0x120>;
|
reg = <0x80200 0x120>;
|
||||||
};
|
};
|
||||||
|
|
||||||
watchdog@803F0 {
|
watchdog@803f0 {
|
||||||
compatible = "lantiq,wdt";
|
compatible = "lantiq,wdt";
|
||||||
reg = <0x803F0 0x10>;
|
reg = <0x803f0 0x10>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sram@1F000000 {
|
sram@1f000000 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "lantiq,sram";
|
compatible = "lantiq,sram";
|
||||||
reg = <0x1F000000 0x800000>;
|
reg = <0x1f000000 0x800000>;
|
||||||
ranges = <0x0 0x1F000000 0x7FFFFF>;
|
ranges = <0x0 0x1f000000 0x7fffff>;
|
||||||
|
|
||||||
eiu0: eiu@101000 {
|
eiu0: eiu@101000 {
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
|
@ -66,41 +66,41 @@
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "lantiq,fpi", "simple-bus";
|
compatible = "lantiq,fpi", "simple-bus";
|
||||||
ranges = <0x0 0x10000000 0xEEFFFFF>;
|
ranges = <0x0 0x10000000 0xeefffff>;
|
||||||
reg = <0x10000000 0xEF00000>;
|
reg = <0x10000000 0xef00000>;
|
||||||
|
|
||||||
gptu@E100A00 {
|
gptu@e100a00 {
|
||||||
compatible = "lantiq,gptu-xway";
|
compatible = "lantiq,gptu-xway";
|
||||||
reg = <0xE100A00 0x100>;
|
reg = <0xe100a00 0x100>;
|
||||||
};
|
};
|
||||||
|
|
||||||
serial@E100C00 {
|
serial@e100c00 {
|
||||||
compatible = "lantiq,asc";
|
compatible = "lantiq,asc";
|
||||||
reg = <0xE100C00 0x400>;
|
reg = <0xe100c00 0x400>;
|
||||||
interrupt-parent = <&icu0>;
|
interrupt-parent = <&icu0>;
|
||||||
interrupts = <112 113 114>;
|
interrupts = <112 113 114>;
|
||||||
};
|
};
|
||||||
|
|
||||||
dma0: dma@E104100 {
|
dma0: dma@e104100 {
|
||||||
compatible = "lantiq,dma-xway";
|
compatible = "lantiq,dma-xway";
|
||||||
reg = <0xE104100 0x800>;
|
reg = <0xe104100 0x800>;
|
||||||
};
|
};
|
||||||
|
|
||||||
ebu0: ebu@E105300 {
|
ebu0: ebu@e105300 {
|
||||||
compatible = "lantiq,ebu-xway";
|
compatible = "lantiq,ebu-xway";
|
||||||
reg = <0xE105300 0x100>;
|
reg = <0xe105300 0x100>;
|
||||||
};
|
};
|
||||||
|
|
||||||
pci0: pci@E105400 {
|
pci0: pci@e105400 {
|
||||||
#address-cells = <3>;
|
#address-cells = <3>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
compatible = "lantiq,pci-xway";
|
compatible = "lantiq,pci-xway";
|
||||||
bus-range = <0x0 0x0>;
|
bus-range = <0x0 0x0>;
|
||||||
ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
|
ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
|
||||||
0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */
|
0x1000000 0 0x00000000 0xae00000 0 0x200000>; /* io space */
|
||||||
reg = <0x7000000 0x8000 /* config space */
|
reg = <0x7000000 0x8000 /* config space */
|
||||||
0xE105400 0x400>; /* pci bridge */
|
0xe105400 0x400>; /* pci bridge */
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,14 +52,14 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio: pinmux@E100B10 {
|
gpio: pinmux@e100b10 {
|
||||||
compatible = "lantiq,danube-pinctrl";
|
compatible = "lantiq,danube-pinctrl";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&state_default>;
|
pinctrl-0 = <&state_default>;
|
||||||
|
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
reg = <0xE100B10 0xA0>;
|
reg = <0xe100b10 0xa0>;
|
||||||
|
|
||||||
state_default: pinmux {
|
state_default: pinmux {
|
||||||
stp {
|
stp {
|
||||||
|
@ -82,26 +82,26 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
etop@E180000 {
|
etop@e180000 {
|
||||||
compatible = "lantiq,etop-xway";
|
compatible = "lantiq,etop-xway";
|
||||||
reg = <0xE180000 0x40000>;
|
reg = <0xe180000 0x40000>;
|
||||||
interrupt-parent = <&icu0>;
|
interrupt-parent = <&icu0>;
|
||||||
interrupts = <73 78>;
|
interrupts = <73 78>;
|
||||||
phy-mode = "rmii";
|
phy-mode = "rmii";
|
||||||
mac-address = [ 00 11 22 33 44 55 ];
|
mac-address = [ 00 11 22 33 44 55 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
stp0: stp@E100BB0 {
|
stp0: stp@e100bb0 {
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
compatible = "lantiq,gpio-stp-xway";
|
compatible = "lantiq,gpio-stp-xway";
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
reg = <0xE100BB0 0x40>;
|
reg = <0xe100bb0 0x40>;
|
||||||
|
|
||||||
lantiq,shadow = <0xfff>;
|
lantiq,shadow = <0xfff>;
|
||||||
lantiq,groups = <0x3>;
|
lantiq,groups = <0x3>;
|
||||||
};
|
};
|
||||||
|
|
||||||
pci@E105400 {
|
pci@e105400 {
|
||||||
lantiq,bus-clock = <33333333>;
|
lantiq,bus-clock = <33333333>;
|
||||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||||
interrupt-map = <
|
interrupt-map = <
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
dtb-$(CONFIG_MSCC_OCELOT) += ocelot_pcb123.dtb
|
dtb-$(CONFIG_MSCC_OCELOT) += ocelot_pcb123.dtb ocelot_pcb120.dtb
|
||||||
|
|
||||||
obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
|
obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
|
||||||
|
|
|
@ -78,6 +78,19 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
i2c: i2c@100400 {
|
||||||
|
compatible = "mscc,ocelot-i2c", "snps,designware-i2c";
|
||||||
|
pinctrl-0 = <&i2c_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
reg = <0x100400 0x100>, <0x198 0x8>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
interrupts = <8>;
|
||||||
|
clocks = <&ahb_clk>;
|
||||||
|
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
uart2: serial@100800 {
|
uart2: serial@100800 {
|
||||||
pinctrl-0 = <&uart2_pins>;
|
pinctrl-0 = <&uart2_pins>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
@ -182,6 +195,11 @@
|
||||||
interrupts = <13>;
|
interrupts = <13>;
|
||||||
#interrupt-cells = <2>;
|
#interrupt-cells = <2>;
|
||||||
|
|
||||||
|
i2c_pins: i2c-pins {
|
||||||
|
pins = "GPIO_16", "GPIO_17";
|
||||||
|
function = "twi";
|
||||||
|
};
|
||||||
|
|
||||||
uart_pins: uart-pins {
|
uart_pins: uart-pins {
|
||||||
pins = "GPIO_6", "GPIO_7";
|
pins = "GPIO_6", "GPIO_7";
|
||||||
function = "uart";
|
function = "uart";
|
||||||
|
@ -196,6 +214,7 @@
|
||||||
pins = "GPIO_14", "GPIO_15";
|
pins = "GPIO_14", "GPIO_15";
|
||||||
function = "miim1";
|
function = "miim1";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mdio0: mdio@107009c {
|
mdio0: mdio@107009c {
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||||
|
/* Copyright (c) 2017 Microsemi Corporation */
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/phy/phy-ocelot-serdes.h>
|
||||||
|
#include "ocelot.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "mscc,ocelot-pcb120", "mscc,ocelot";
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = "serial0:115200n8";
|
||||||
|
};
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0x0 0x0e000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gpio {
|
||||||
|
phy_int_pins: phy_int_pins {
|
||||||
|
pins = "GPIO_4";
|
||||||
|
function = "gpio";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&mdio0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&mdio1 {
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&miim1>, <&phy_int_pins>;
|
||||||
|
|
||||||
|
phy7: ethernet-phy@0 {
|
||||||
|
reg = <0>;
|
||||||
|
interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
};
|
||||||
|
phy6: ethernet-phy@1 {
|
||||||
|
reg = <1>;
|
||||||
|
interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
};
|
||||||
|
phy5: ethernet-phy@2 {
|
||||||
|
reg = <2>;
|
||||||
|
interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
};
|
||||||
|
phy4: ethernet-phy@3 {
|
||||||
|
reg = <3>;
|
||||||
|
interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&port0 {
|
||||||
|
phy-handle = <&phy0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port1 {
|
||||||
|
phy-handle = <&phy1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port2 {
|
||||||
|
phy-handle = <&phy2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port3 {
|
||||||
|
phy-handle = <&phy3>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port4 {
|
||||||
|
phy-handle = <&phy7>;
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
phys = <&serdes 4 SERDES1G(2)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port5 {
|
||||||
|
phy-handle = <&phy4>;
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
phys = <&serdes 5 SERDES1G(5)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port6 {
|
||||||
|
phy-handle = <&phy6>;
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
phys = <&serdes 6 SERDES1G(3)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&port9 {
|
||||||
|
phy-handle = <&phy5>;
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
phys = <&serdes 9 SERDES1G(4)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart2 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
|
@ -36,6 +36,12 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&i2c {
|
||||||
|
clock-frequency = <100000>;
|
||||||
|
i2c-sda-hold-time-ns = <300>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
&mdio0 {
|
&mdio0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1180,8 +1180,8 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
|
||||||
type = IRQ_TYPE_LEVEL_LOW;
|
type = IRQ_TYPE_LEVEL_LOW;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Error: (%s) Invalid irq trigger specification: %x\n",
|
pr_err("Error: (%pOFn) Invalid irq trigger specification: %x\n",
|
||||||
node->name,
|
node,
|
||||||
trigger);
|
trigger);
|
||||||
type = IRQ_TYPE_LEVEL_LOW;
|
type = IRQ_TYPE_LEVEL_LOW;
|
||||||
break;
|
break;
|
||||||
|
@ -2271,8 +2271,8 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||||
|
|
||||||
parent_irq = irq_of_parse_and_map(ciu_node, 0);
|
parent_irq = irq_of_parse_and_map(ciu_node, 0);
|
||||||
if (!parent_irq) {
|
if (!parent_irq) {
|
||||||
pr_err("ERROR: Couldn't acquire parent_irq for %s\n",
|
pr_err("ERROR: Couldn't acquire parent_irq for %pOFn\n",
|
||||||
ciu_node->name);
|
ciu_node);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2283,7 +2283,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||||
|
|
||||||
addr = of_get_address(ciu_node, 0, NULL, NULL);
|
addr = of_get_address(ciu_node, 0, NULL, NULL);
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
pr_err("ERROR: Couldn't acquire reg(0) %s\n", ciu_node->name);
|
pr_err("ERROR: Couldn't acquire reg(0) %pOFn\n", ciu_node);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
host_data->raw_reg = (u64)phys_to_virt(
|
host_data->raw_reg = (u64)phys_to_virt(
|
||||||
|
@ -2291,7 +2291,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||||
|
|
||||||
addr = of_get_address(ciu_node, 1, NULL, NULL);
|
addr = of_get_address(ciu_node, 1, NULL, NULL);
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
pr_err("ERROR: Couldn't acquire reg(1) %s\n", ciu_node->name);
|
pr_err("ERROR: Couldn't acquire reg(1) %pOFn\n", ciu_node);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
host_data->en_reg = (u64)phys_to_virt(
|
host_data->en_reg = (u64)phys_to_virt(
|
||||||
|
@ -2299,8 +2299,8 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
||||||
|
|
||||||
r = of_property_read_u32(ciu_node, "cavium,max-bits", &val);
|
r = of_property_read_u32(ciu_node, "cavium,max-bits", &val);
|
||||||
if (r) {
|
if (r) {
|
||||||
pr_err("ERROR: Couldn't read cavium,max-bits from %s\n",
|
pr_err("ERROR: Couldn't read cavium,max-bits from %pOFn\n",
|
||||||
ciu_node->name);
|
ciu_node);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
host_data->max_bits = val;
|
host_data->max_bits = val;
|
||||||
|
|
|
@ -1161,15 +1161,12 @@ void __init device_tree_init(void)
|
||||||
bool do_prune;
|
bool do_prune;
|
||||||
bool fill_mac;
|
bool fill_mac;
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_ELF_APPENDED_DTB
|
if (fw_passed_dtb) {
|
||||||
if (!fdt_check_header(&__appended_dtb)) {
|
fdt = (void *)fw_passed_dtb;
|
||||||
fdt = &__appended_dtb;
|
|
||||||
do_prune = false;
|
do_prune = false;
|
||||||
fill_mac = true;
|
fill_mac = true;
|
||||||
pr_info("Using appended Device Tree.\n");
|
pr_info("Using appended Device Tree.\n");
|
||||||
} else
|
} else if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
|
||||||
#endif
|
|
||||||
if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
|
|
||||||
fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
|
fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
|
||||||
if (fdt_check_header(fdt))
|
if (fdt_check_header(fdt))
|
||||||
panic("Corrupt Device Tree passed to kernel.");
|
panic("Corrupt Device Tree passed to kernel.");
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/sched/task_stack.h>
|
#include <linux/sched/task_stack.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
|
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
|
@ -424,6 +425,9 @@ const struct plat_smp_ops octeon_smp_ops = {
|
||||||
.cpu_disable = octeon_cpu_disable,
|
.cpu_disable = octeon_cpu_disable,
|
||||||
.cpu_die = octeon_cpu_die,
|
.cpu_die = octeon_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static irqreturn_t octeon_78xx_reched_interrupt(int irq, void *dev_id)
|
static irqreturn_t octeon_78xx_reched_interrupt(int irq, void *dev_id)
|
||||||
|
@ -501,6 +505,9 @@ static const struct plat_smp_ops octeon_78xx_smp_ops = {
|
||||||
.cpu_disable = octeon_cpu_disable,
|
.cpu_disable = octeon_cpu_disable,
|
||||||
.cpu_die = octeon_cpu_die,
|
.cpu_die = octeon_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init octeon_setup_smp(void)
|
void __init octeon_setup_smp(void)
|
||||||
|
|
|
@ -18,17 +18,25 @@ CONFIG_SERIAL_8250=y
|
||||||
CONFIG_SERIAL_8250_CONSOLE=y
|
CONFIG_SERIAL_8250_CONSOLE=y
|
||||||
CONFIG_SERIAL_OF_PLATFORM=y
|
CONFIG_SERIAL_OF_PLATFORM=y
|
||||||
|
|
||||||
CONFIG_GPIO_SYSFS=y
|
CONFIG_NETDEVICES=y
|
||||||
|
CONFIG_MSCC_OCELOT_SWITCH=y
|
||||||
|
CONFIG_MSCC_OCELOT_SWITCH_OCELOT=y
|
||||||
|
CONFIG_MDIO_MSCC_MIIM=y
|
||||||
|
CONFIG_MICROSEMI_PHY=y
|
||||||
|
|
||||||
CONFIG_I2C=y
|
CONFIG_I2C=y
|
||||||
CONFIG_I2C_CHARDEV=y
|
CONFIG_I2C_CHARDEV=y
|
||||||
CONFIG_I2C_MUX=y
|
CONFIG_I2C_MUX=y
|
||||||
|
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||||
|
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SPI_BITBANG=y
|
CONFIG_SPI_BITBANG=y
|
||||||
CONFIG_SPI_DESIGNWARE=y
|
CONFIG_SPI_DESIGNWARE=y
|
||||||
|
CONFIG_SPI_DW_MMIO=y
|
||||||
CONFIG_SPI_SPIDEV=y
|
CONFIG_SPI_SPIDEV=y
|
||||||
|
|
||||||
|
CONFIG_GPIO_SYSFS=y
|
||||||
|
|
||||||
CONFIG_POWER_RESET=y
|
CONFIG_POWER_RESET=y
|
||||||
CONFIG_POWER_RESET_OCELOT_RESET=y
|
CONFIG_POWER_RESET_OCELOT_RESET=y
|
||||||
|
|
||||||
|
|
|
@ -65,11 +65,11 @@ config FIT_IMAGE_FDT_XILFPGA
|
||||||
Enable this to include the FDT for the MIPSfpga platform
|
Enable this to include the FDT for the MIPSfpga platform
|
||||||
from Imagination Technologies in the FIT kernel image.
|
from Imagination Technologies in the FIT kernel image.
|
||||||
|
|
||||||
config FIT_IMAGE_FDT_OCELOT_PCB123
|
config FIT_IMAGE_FDT_OCELOT
|
||||||
bool "Include FDT for Microsemi Ocelot PCB123"
|
bool "Include FDT for Microsemi Ocelot development platforms"
|
||||||
select MSCC_OCELOT
|
select MSCC_OCELOT
|
||||||
help
|
help
|
||||||
Enable this to include the FDT for the Ocelot PCB123 platform
|
Enable this to include the FDT for the Ocelot development platforms
|
||||||
from Microsemi in the FIT kernel image.
|
from Microsemi in the FIT kernel image.
|
||||||
This requires u-boot on the platform.
|
This requires u-boot on the platform.
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,4 @@ obj-y += proc.o
|
||||||
obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
|
obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
|
||||||
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
|
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
|
||||||
obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o
|
obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o
|
||||||
obj-$(CONFIG_KEXEC) += kexec.o
|
|
||||||
obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o
|
obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o
|
||||||
|
|
|
@ -16,5 +16,5 @@ all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb
|
||||||
its-y := vmlinux.its.S
|
its-y := vmlinux.its.S
|
||||||
its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S
|
its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S
|
||||||
its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S
|
its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S
|
||||||
its-$(CONFIG_FIT_IMAGE_FDT_OCELOT_PCB123) += board-ocelot_pcb123.its.S
|
its-$(CONFIG_FIT_IMAGE_FDT_OCELOT) += board-ocelot.its.S
|
||||||
its-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += board-xilfpga.its.S
|
its-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += board-xilfpga.its.S
|
||||||
|
|
|
@ -11,6 +11,17 @@
|
||||||
algo = "sha1";
|
algo = "sha1";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fdt@ocelot_pcb120 {
|
||||||
|
description = "MSCC Ocelot PCB120 Device Tree";
|
||||||
|
data = /incbin/("boot/dts/mscc/ocelot_pcb120.dtb");
|
||||||
|
type = "flat_dt";
|
||||||
|
arch = "mips";
|
||||||
|
compression = "none";
|
||||||
|
hash@0 {
|
||||||
|
algo = "sha1";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
|
@ -19,5 +30,11 @@
|
||||||
kernel = "kernel@0";
|
kernel = "kernel@0";
|
||||||
fdt = "fdt@ocelot_pcb123";
|
fdt = "fdt@ocelot_pcb123";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
conf@ocelot_pcb120 {
|
||||||
|
description = "Ocelot Linux kernel";
|
||||||
|
kernel = "kernel@0";
|
||||||
|
fdt = "fdt@ocelot_pcb120";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 Imagination Technologies
|
|
||||||
* Author: Marcin Nowakowski <marcin.nowakowski@mips.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kexec.h>
|
|
||||||
#include <linux/libfdt.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
|
|
||||||
static int generic_kexec_prepare(struct kimage *image)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < image->nr_segments; i++) {
|
|
||||||
struct fdt_header fdt;
|
|
||||||
|
|
||||||
if (image->segment[i].memsz <= sizeof(fdt))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fdt_check_header(&fdt))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
kexec_args[0] = -2;
|
|
||||||
kexec_args[1] = (unsigned long)
|
|
||||||
phys_to_virt((unsigned long)image->segment[i].mem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init register_generic_kexec(void)
|
|
||||||
{
|
|
||||||
_machine_kexec_prepare = generic_kexec_prepare;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
arch_initcall(register_generic_kexec);
|
|
|
@ -15,6 +15,7 @@
|
||||||
/* Kernel variants */
|
/* Kernel variants */
|
||||||
|
|
||||||
#define kernel_cache(op, base) "cache " op ", " base "\n"
|
#define kernel_cache(op, base) "cache " op ", " base "\n"
|
||||||
|
#define kernel_pref(hint, base) "pref " hint ", " base "\n"
|
||||||
#define kernel_ll(reg, addr) "ll " reg ", " addr "\n"
|
#define kernel_ll(reg, addr) "ll " reg ", " addr "\n"
|
||||||
#define kernel_sc(reg, addr) "sc " reg ", " addr "\n"
|
#define kernel_sc(reg, addr) "sc " reg ", " addr "\n"
|
||||||
#define kernel_lw(reg, addr) "lw " reg ", " addr "\n"
|
#define kernel_lw(reg, addr) "lw " reg ", " addr "\n"
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
" .set pop\n"
|
" .set pop\n"
|
||||||
|
|
||||||
#define user_cache(op, base) __BUILD_EVA_INSN("cachee", op, base)
|
#define user_cache(op, base) __BUILD_EVA_INSN("cachee", op, base)
|
||||||
|
#define user_pref(hint, base) __BUILD_EVA_INSN("prefe", hint, base)
|
||||||
#define user_ll(reg, addr) __BUILD_EVA_INSN("lle", reg, addr)
|
#define user_ll(reg, addr) __BUILD_EVA_INSN("lle", reg, addr)
|
||||||
#define user_sc(reg, addr) __BUILD_EVA_INSN("sce", reg, addr)
|
#define user_sc(reg, addr) __BUILD_EVA_INSN("sce", reg, addr)
|
||||||
#define user_lw(reg, addr) __BUILD_EVA_INSN("lwe", reg, addr)
|
#define user_lw(reg, addr) __BUILD_EVA_INSN("lwe", reg, addr)
|
||||||
|
@ -72,6 +74,7 @@
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define user_cache(op, base) kernel_cache(op, base)
|
#define user_cache(op, base) kernel_cache(op, base)
|
||||||
|
#define user_pref(hint, base) kernel_pref(hint, base)
|
||||||
#define user_ll(reg, addr) kernel_ll(reg, addr)
|
#define user_ll(reg, addr) kernel_ll(reg, addr)
|
||||||
#define user_sc(reg, addr) kernel_sc(reg, addr)
|
#define user_sc(reg, addr) kernel_sc(reg, addr)
|
||||||
#define user_lw(reg, addr) kernel_lw(reg, addr)
|
#define user_lw(reg, addr) kernel_lw(reg, addr)
|
||||||
|
@ -99,6 +102,7 @@
|
||||||
#else /* __ASSEMBLY__ */
|
#else /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#define kernel_cache(op, base) cache op, base
|
#define kernel_cache(op, base) cache op, base
|
||||||
|
#define kernel_pref(hint, base) pref hint, base
|
||||||
#define kernel_ll(reg, addr) ll reg, addr
|
#define kernel_ll(reg, addr) ll reg, addr
|
||||||
#define kernel_sc(reg, addr) sc reg, addr
|
#define kernel_sc(reg, addr) sc reg, addr
|
||||||
#define kernel_lw(reg, addr) lw reg, addr
|
#define kernel_lw(reg, addr) lw reg, addr
|
||||||
|
@ -135,6 +139,7 @@
|
||||||
.set pop;
|
.set pop;
|
||||||
|
|
||||||
#define user_cache(op, base) __BUILD_EVA_INSN(cachee, op, base)
|
#define user_cache(op, base) __BUILD_EVA_INSN(cachee, op, base)
|
||||||
|
#define user_pref(hint, base) __BUILD_EVA_INSN(prefe, hint, base)
|
||||||
#define user_ll(reg, addr) __BUILD_EVA_INSN(lle, reg, addr)
|
#define user_ll(reg, addr) __BUILD_EVA_INSN(lle, reg, addr)
|
||||||
#define user_sc(reg, addr) __BUILD_EVA_INSN(sce, reg, addr)
|
#define user_sc(reg, addr) __BUILD_EVA_INSN(sce, reg, addr)
|
||||||
#define user_lw(reg, addr) __BUILD_EVA_INSN(lwe, reg, addr)
|
#define user_lw(reg, addr) __BUILD_EVA_INSN(lwe, reg, addr)
|
||||||
|
@ -155,6 +160,7 @@
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define user_cache(op, base) kernel_cache(op, base)
|
#define user_cache(op, base) kernel_cache(op, base)
|
||||||
|
#define user_pref(hint, base) kernel_pref(hint, base)
|
||||||
#define user_ll(reg, addr) kernel_ll(reg, addr)
|
#define user_ll(reg, addr) kernel_ll(reg, addr)
|
||||||
#define user_sc(reg, addr) kernel_sc(reg, addr)
|
#define user_sc(reg, addr) kernel_sc(reg, addr)
|
||||||
#define user_lw(reg, addr) kernel_lw(reg, addr)
|
#define user_lw(reg, addr) kernel_lw(reg, addr)
|
||||||
|
|
|
@ -20,32 +20,6 @@
|
||||||
#include <asm/sgidefs.h>
|
#include <asm/sgidefs.h>
|
||||||
#include <asm/asm-eva.h>
|
#include <asm/asm-eva.h>
|
||||||
|
|
||||||
#ifndef CAT
|
|
||||||
#ifdef __STDC__
|
|
||||||
#define __CAT(str1, str2) str1##str2
|
|
||||||
#else
|
|
||||||
#define __CAT(str1, str2) str1/**/str2
|
|
||||||
#endif
|
|
||||||
#define CAT(str1, str2) __CAT(str1, str2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PIC specific declarations
|
|
||||||
* Not used for the kernel but here seems to be the right place.
|
|
||||||
*/
|
|
||||||
#ifdef __PIC__
|
|
||||||
#define CPRESTORE(register) \
|
|
||||||
.cprestore register
|
|
||||||
#define CPADD(register) \
|
|
||||||
.cpadd register
|
|
||||||
#define CPLOAD(register) \
|
|
||||||
.cpload register
|
|
||||||
#else
|
|
||||||
#define CPRESTORE(register)
|
|
||||||
#define CPADD(register)
|
|
||||||
#define CPLOAD(register)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LEAF - declare leaf routine
|
* LEAF - declare leaf routine
|
||||||
*/
|
*/
|
||||||
|
@ -129,96 +103,6 @@ symbol = value
|
||||||
8: .asciiz msg; \
|
8: .asciiz msg; \
|
||||||
.popsection;
|
.popsection;
|
||||||
|
|
||||||
/*
|
|
||||||
* Build text tables
|
|
||||||
*/
|
|
||||||
#define TTABLE(string) \
|
|
||||||
.pushsection .text; \
|
|
||||||
.word 1f; \
|
|
||||||
.popsection \
|
|
||||||
.pushsection .data; \
|
|
||||||
1: .asciiz string; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MIPS IV pref instruction.
|
|
||||||
* Use with .set noreorder only!
|
|
||||||
*
|
|
||||||
* MIPS IV implementations are free to treat this as a nop. The R5000
|
|
||||||
* is one of them. So we should have an option not to use this instruction.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_CPU_HAS_PREFETCH
|
|
||||||
|
|
||||||
#define PREF(hint,addr) \
|
|
||||||
.set push; \
|
|
||||||
.set arch=r5000; \
|
|
||||||
pref hint, addr; \
|
|
||||||
.set pop
|
|
||||||
|
|
||||||
#define PREFE(hint, addr) \
|
|
||||||
.set push; \
|
|
||||||
.set mips0; \
|
|
||||||
.set eva; \
|
|
||||||
prefe hint, addr; \
|
|
||||||
.set pop
|
|
||||||
|
|
||||||
#define PREFX(hint,addr) \
|
|
||||||
.set push; \
|
|
||||||
.set arch=r5000; \
|
|
||||||
prefx hint, addr; \
|
|
||||||
.set pop
|
|
||||||
|
|
||||||
#else /* !CONFIG_CPU_HAS_PREFETCH */
|
|
||||||
|
|
||||||
#define PREF(hint, addr)
|
|
||||||
#define PREFE(hint, addr)
|
|
||||||
#define PREFX(hint, addr)
|
|
||||||
|
|
||||||
#endif /* !CONFIG_CPU_HAS_PREFETCH */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
|
|
||||||
*/
|
|
||||||
#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
|
|
||||||
#define MOVN(rd, rs, rt) \
|
|
||||||
.set push; \
|
|
||||||
.set reorder; \
|
|
||||||
beqz rt, 9f; \
|
|
||||||
move rd, rs; \
|
|
||||||
.set pop; \
|
|
||||||
9:
|
|
||||||
#define MOVZ(rd, rs, rt) \
|
|
||||||
.set push; \
|
|
||||||
.set reorder; \
|
|
||||||
bnez rt, 9f; \
|
|
||||||
move rd, rs; \
|
|
||||||
.set pop; \
|
|
||||||
9:
|
|
||||||
#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
|
|
||||||
#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
|
|
||||||
#define MOVN(rd, rs, rt) \
|
|
||||||
.set push; \
|
|
||||||
.set noreorder; \
|
|
||||||
bnezl rt, 9f; \
|
|
||||||
move rd, rs; \
|
|
||||||
.set pop; \
|
|
||||||
9:
|
|
||||||
#define MOVZ(rd, rs, rt) \
|
|
||||||
.set push; \
|
|
||||||
.set noreorder; \
|
|
||||||
beqzl rt, 9f; \
|
|
||||||
move rd, rs; \
|
|
||||||
.set pop; \
|
|
||||||
9:
|
|
||||||
#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
|
|
||||||
#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
|
|
||||||
(_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
|
|
||||||
#define MOVN(rd, rs, rt) \
|
|
||||||
movn rd, rs, rt
|
|
||||||
#define MOVZ(rd, rs, rt) \
|
|
||||||
movz rd, rs, rt
|
|
||||||
#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stack alignment
|
* Stack alignment
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
|
||||||
#include <asm/addrspace.h>
|
#include <asm/addrspace.h>
|
||||||
|
#include <asm/barrier.h>
|
||||||
#include <asm/bug.h>
|
#include <asm/bug.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
@ -33,11 +34,6 @@
|
||||||
#include <ioremap.h>
|
#include <ioremap.h>
|
||||||
#include <mangle-port.h>
|
#include <mangle-port.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Slowdown I/O port space accesses for antique hardware.
|
|
||||||
*/
|
|
||||||
#undef CONF_SLOWDOWN_IO
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Raw operations are never swapped in software. OTOH values that raw
|
* Raw operations are never swapped in software. OTOH values that raw
|
||||||
* operations are working on may or may not have been swapped by the bus
|
* operations are working on may or may not have been swapped by the bus
|
||||||
|
@ -50,6 +46,11 @@
|
||||||
# define __raw_ioswabq(a, x) (x)
|
# define __raw_ioswabq(a, x) (x)
|
||||||
# define ____raw_ioswabq(a, x) (x)
|
# define ____raw_ioswabq(a, x) (x)
|
||||||
|
|
||||||
|
# define __relaxed_ioswabb ioswabb
|
||||||
|
# define __relaxed_ioswabw ioswabw
|
||||||
|
# define __relaxed_ioswabl ioswabl
|
||||||
|
# define __relaxed_ioswabq ioswabq
|
||||||
|
|
||||||
/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
|
/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
|
||||||
|
|
||||||
#define IO_SPACE_LIMIT 0xffff
|
#define IO_SPACE_LIMIT 0xffff
|
||||||
|
@ -80,31 +81,29 @@ static inline void set_io_port_base(unsigned long base)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thanks to James van Artsdalen for a better timing-fix than
|
* Provide the necessary definitions for generic iomap. We make use of
|
||||||
* the two short jumps: using outb's to a nonexistent port seems
|
* mips_io_port_base for iomap(), but we don't reserve any low addresses for
|
||||||
* to guarantee better timings even on fast machines.
|
* use with I/O ports.
|
||||||
*
|
|
||||||
* On the other hand, I'd like to be sure of a non-existent port:
|
|
||||||
* I feel a bit unsafe about using 0x80 (should be safe, though)
|
|
||||||
*
|
|
||||||
* Linus
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define __SLOW_DOWN_IO \
|
#define HAVE_ARCH_PIO_SIZE
|
||||||
__asm__ __volatile__( \
|
#define PIO_OFFSET mips_io_port_base
|
||||||
"sb\t$0,0x80(%0)" \
|
#define PIO_MASK IO_SPACE_LIMIT
|
||||||
: : "r" (mips_io_port_base));
|
#define PIO_RESERVED 0x0UL
|
||||||
|
|
||||||
#ifdef CONF_SLOWDOWN_IO
|
/*
|
||||||
#ifdef REALLY_SLOW_IO
|
* Enforce in-order execution of data I/O. In the MIPS architecture
|
||||||
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
|
* these are equivalent to corresponding platform-specific memory
|
||||||
#else
|
* barriers defined in <asm/barrier.h>. API pinched from PowerPC,
|
||||||
#define SLOW_DOWN_IO __SLOW_DOWN_IO
|
* with sync additionally defined.
|
||||||
#endif
|
*/
|
||||||
#else
|
#define iobarrier_rw() mb()
|
||||||
#define SLOW_DOWN_IO
|
#define iobarrier_r() rmb()
|
||||||
#endif
|
#define iobarrier_w() wmb()
|
||||||
|
#define iobarrier_sync() iob()
|
||||||
|
|
||||||
|
/* Some callers use this older API instead. */
|
||||||
|
#define mmiowb() iobarrier_w()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* virt_to_phys - map virtual addresses to physical
|
* virt_to_phys - map virtual addresses to physical
|
||||||
|
@ -172,11 +171,6 @@ static inline void *isa_bus_to_virt(unsigned long address)
|
||||||
extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
|
extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
|
||||||
extern void __iounmap(const volatile void __iomem *addr);
|
extern void __iounmap(const volatile void __iomem *addr);
|
||||||
|
|
||||||
#ifndef CONFIG_PCI
|
|
||||||
struct pci_dev;
|
|
||||||
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
|
static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
|
@ -316,13 +310,13 @@ static inline void iounmap(const volatile void __iomem *addr)
|
||||||
#undef __IS_KSEG1
|
#undef __IS_KSEG1
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT)
|
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_CPU_LOONGSON3)
|
||||||
#define war_io_reorder_wmb() wmb()
|
#define war_io_reorder_wmb() wmb()
|
||||||
#else
|
#else
|
||||||
#define war_io_reorder_wmb() barrier()
|
#define war_io_reorder_wmb() barrier()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
|
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, barrier, relax, irq) \
|
||||||
\
|
\
|
||||||
static inline void pfx##write##bwlq(type val, \
|
static inline void pfx##write##bwlq(type val, \
|
||||||
volatile void __iomem *mem) \
|
volatile void __iomem *mem) \
|
||||||
|
@ -330,7 +324,10 @@ static inline void pfx##write##bwlq(type val, \
|
||||||
volatile type *__mem; \
|
volatile type *__mem; \
|
||||||
type __val; \
|
type __val; \
|
||||||
\
|
\
|
||||||
war_io_reorder_wmb(); \
|
if (barrier) \
|
||||||
|
iobarrier_rw(); \
|
||||||
|
else \
|
||||||
|
war_io_reorder_wmb(); \
|
||||||
\
|
\
|
||||||
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
|
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
|
||||||
\
|
\
|
||||||
|
@ -367,6 +364,9 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
|
||||||
\
|
\
|
||||||
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
|
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
|
||||||
\
|
\
|
||||||
|
if (barrier) \
|
||||||
|
iobarrier_rw(); \
|
||||||
|
\
|
||||||
if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
|
if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
|
||||||
__val = *__mem; \
|
__val = *__mem; \
|
||||||
else if (cpu_has_64bits) { \
|
else if (cpu_has_64bits) { \
|
||||||
|
@ -390,18 +390,22 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* prevent prefetching of coherent DMA data prematurely */ \
|
/* prevent prefetching of coherent DMA data prematurely */ \
|
||||||
rmb(); \
|
if (!relax) \
|
||||||
|
rmb(); \
|
||||||
return pfx##ioswab##bwlq(__mem, __val); \
|
return pfx##ioswab##bwlq(__mem, __val); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
|
#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, barrier, relax, p) \
|
||||||
\
|
\
|
||||||
static inline void pfx##out##bwlq##p(type val, unsigned long port) \
|
static inline void pfx##out##bwlq##p(type val, unsigned long port) \
|
||||||
{ \
|
{ \
|
||||||
volatile type *__addr; \
|
volatile type *__addr; \
|
||||||
type __val; \
|
type __val; \
|
||||||
\
|
\
|
||||||
war_io_reorder_wmb(); \
|
if (barrier) \
|
||||||
|
iobarrier_rw(); \
|
||||||
|
else \
|
||||||
|
war_io_reorder_wmb(); \
|
||||||
\
|
\
|
||||||
__addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
|
__addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
|
||||||
\
|
\
|
||||||
|
@ -411,7 +415,6 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
|
||||||
BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
|
BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
|
||||||
\
|
\
|
||||||
*__addr = __val; \
|
*__addr = __val; \
|
||||||
slow; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline type pfx##in##bwlq##p(unsigned long port) \
|
static inline type pfx##in##bwlq##p(unsigned long port) \
|
||||||
|
@ -423,23 +426,27 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
|
||||||
\
|
\
|
||||||
BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
|
BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
|
||||||
\
|
\
|
||||||
|
if (barrier) \
|
||||||
|
iobarrier_rw(); \
|
||||||
|
\
|
||||||
__val = *__addr; \
|
__val = *__addr; \
|
||||||
slow; \
|
|
||||||
\
|
\
|
||||||
/* prevent prefetching of coherent DMA data prematurely */ \
|
/* prevent prefetching of coherent DMA data prematurely */ \
|
||||||
rmb(); \
|
if (!relax) \
|
||||||
|
rmb(); \
|
||||||
return pfx##ioswab##bwlq(__addr, __val); \
|
return pfx##ioswab##bwlq(__addr, __val); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __BUILD_MEMORY_PFX(bus, bwlq, type) \
|
#define __BUILD_MEMORY_PFX(bus, bwlq, type, relax) \
|
||||||
\
|
\
|
||||||
__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
|
__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1, relax, 1)
|
||||||
|
|
||||||
#define BUILDIO_MEM(bwlq, type) \
|
#define BUILDIO_MEM(bwlq, type) \
|
||||||
\
|
\
|
||||||
__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
|
__BUILD_MEMORY_PFX(__raw_, bwlq, type, 0) \
|
||||||
__BUILD_MEMORY_PFX(, bwlq, type) \
|
__BUILD_MEMORY_PFX(__relaxed_, bwlq, type, 1) \
|
||||||
__BUILD_MEMORY_PFX(__mem_, bwlq, type) \
|
__BUILD_MEMORY_PFX(__mem_, bwlq, type, 0) \
|
||||||
|
__BUILD_MEMORY_PFX(, bwlq, type, 0)
|
||||||
|
|
||||||
BUILDIO_MEM(b, u8)
|
BUILDIO_MEM(b, u8)
|
||||||
BUILDIO_MEM(w, u16)
|
BUILDIO_MEM(w, u16)
|
||||||
|
@ -447,8 +454,8 @@ BUILDIO_MEM(l, u32)
|
||||||
BUILDIO_MEM(q, u64)
|
BUILDIO_MEM(q, u64)
|
||||||
|
|
||||||
#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
|
#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
|
||||||
__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
|
__BUILD_IOPORT_SINGLE(bus, bwlq, type, 1, 0,) \
|
||||||
__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
|
__BUILD_IOPORT_SINGLE(bus, bwlq, type, 1, 0, _p)
|
||||||
|
|
||||||
#define BUILDIO_IOPORT(bwlq, type) \
|
#define BUILDIO_IOPORT(bwlq, type) \
|
||||||
__BUILD_IOPORT_PFX(, bwlq, type) \
|
__BUILD_IOPORT_PFX(, bwlq, type) \
|
||||||
|
@ -463,19 +470,19 @@ BUILDIO_IOPORT(q, u64)
|
||||||
|
|
||||||
#define __BUILDIO(bwlq, type) \
|
#define __BUILDIO(bwlq, type) \
|
||||||
\
|
\
|
||||||
__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
|
__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 1, 0, 0)
|
||||||
|
|
||||||
__BUILDIO(q, u64)
|
__BUILDIO(q, u64)
|
||||||
|
|
||||||
#define readb_relaxed readb
|
#define readb_relaxed __relaxed_readb
|
||||||
#define readw_relaxed readw
|
#define readw_relaxed __relaxed_readw
|
||||||
#define readl_relaxed readl
|
#define readl_relaxed __relaxed_readl
|
||||||
#define readq_relaxed readq
|
#define readq_relaxed __relaxed_readq
|
||||||
|
|
||||||
#define writeb_relaxed writeb
|
#define writeb_relaxed __relaxed_writeb
|
||||||
#define writew_relaxed writew
|
#define writew_relaxed __relaxed_writew
|
||||||
#define writel_relaxed writel
|
#define writel_relaxed __relaxed_writel
|
||||||
#define writeq_relaxed writeq
|
#define writeq_relaxed __relaxed_writeq
|
||||||
|
|
||||||
#define readb_be(addr) \
|
#define readb_be(addr) \
|
||||||
__raw_readb((__force unsigned *)(addr))
|
__raw_readb((__force unsigned *)(addr))
|
||||||
|
@ -561,14 +568,6 @@ BUILDSTRING(l, u32)
|
||||||
BUILDSTRING(q, u64)
|
BUILDSTRING(q, u64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
|
||||||
#define mmiowb() wmb()
|
|
||||||
#else
|
|
||||||
/* Depends on MIPS II instruction set */
|
|
||||||
#define mmiowb() asm volatile ("sync" ::: "memory")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
|
static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
|
||||||
{
|
{
|
||||||
memset((void __force *) addr, val, count);
|
memset((void __force *) addr, val, count);
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
#include <asm/stacktrace.h>
|
#include <asm/stacktrace.h>
|
||||||
|
|
||||||
/* Maximum physical address we can use pages from */
|
/* Maximum physical address we can use pages from */
|
||||||
#define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000)
|
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
|
||||||
/* Maximum address we can reach in physical address mode */
|
/* Maximum address we can reach in physical address mode */
|
||||||
#define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000)
|
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
|
||||||
/* Maximum address we can use for the control code buffer */
|
/* Maximum address we can use for the control code buffer */
|
||||||
#define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000)
|
#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
|
||||||
/* Reserve 3*4096 bytes for board-specific info */
|
/* Reserve 3*4096 bytes for board-specific info */
|
||||||
#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096)
|
#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096)
|
||||||
|
|
||||||
|
@ -39,11 +39,12 @@ extern unsigned long kexec_args[4];
|
||||||
extern int (*_machine_kexec_prepare)(struct kimage *);
|
extern int (*_machine_kexec_prepare)(struct kimage *);
|
||||||
extern void (*_machine_kexec_shutdown)(void);
|
extern void (*_machine_kexec_shutdown)(void);
|
||||||
extern void (*_machine_crash_shutdown)(struct pt_regs *regs);
|
extern void (*_machine_crash_shutdown)(struct pt_regs *regs);
|
||||||
extern void default_machine_crash_shutdown(struct pt_regs *regs);
|
void default_machine_crash_shutdown(struct pt_regs *regs);
|
||||||
|
void kexec_nonboot_cpu_jump(void);
|
||||||
|
void kexec_reboot(void);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
extern const unsigned char kexec_smp_wait[];
|
extern const unsigned char kexec_smp_wait[];
|
||||||
extern unsigned long secondary_kexec_args[4];
|
extern unsigned long secondary_kexec_args[4];
|
||||||
extern void (*relocated_kexec_smp_wait) (void *);
|
|
||||||
extern atomic_t kexec_ready_to_reboot;
|
extern atomic_t kexec_ready_to_reboot;
|
||||||
extern void (*_crash_smp_send_stop)(void);
|
extern void (*_crash_smp_send_stop)(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#define MIPS_CPU_IRQ_BASE 56
|
#define MIPS_CPU_IRQ_BASE 56
|
||||||
|
|
||||||
#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */
|
#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */
|
||||||
#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */
|
#define LOONGSON_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 3) /* CASCADE */
|
||||||
#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */
|
#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */
|
||||||
|
|
||||||
#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base
|
#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
|
#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
|
||||||
#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
|
#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
|
||||||
|
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override macros used in arch/mips/kernel/head.S.
|
* Override macros used in arch/mips/kernel/head.S.
|
||||||
*/
|
*/
|
||||||
|
@ -26,12 +28,15 @@
|
||||||
mfc0 t0, CP0_PAGEGRAIN
|
mfc0 t0, CP0_PAGEGRAIN
|
||||||
or t0, (0x1 << 29)
|
or t0, (0x1 << 29)
|
||||||
mtc0 t0, CP0_PAGEGRAIN
|
mtc0 t0, CP0_PAGEGRAIN
|
||||||
#ifdef CONFIG_LOONGSON3_ENHANCEMENT
|
|
||||||
/* Enable STFill Buffer */
|
/* Enable STFill Buffer */
|
||||||
|
mfc0 t0, CP0_PRID
|
||||||
|
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
|
||||||
|
slti t0, (PRID_IMP_LOONGSON_64 | PRID_REV_LOONGSON3A_R2)
|
||||||
|
bnez t0, 1f
|
||||||
mfc0 t0, CP0_CONFIG6
|
mfc0 t0, CP0_CONFIG6
|
||||||
or t0, 0x100
|
or t0, 0x100
|
||||||
mtc0 t0, CP0_CONFIG6
|
mtc0 t0, CP0_CONFIG6
|
||||||
#endif
|
1:
|
||||||
_ehb
|
_ehb
|
||||||
.set pop
|
.set pop
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,12 +57,15 @@
|
||||||
mfc0 t0, CP0_PAGEGRAIN
|
mfc0 t0, CP0_PAGEGRAIN
|
||||||
or t0, (0x1 << 29)
|
or t0, (0x1 << 29)
|
||||||
mtc0 t0, CP0_PAGEGRAIN
|
mtc0 t0, CP0_PAGEGRAIN
|
||||||
#ifdef CONFIG_LOONGSON3_ENHANCEMENT
|
|
||||||
/* Enable STFill Buffer */
|
/* Enable STFill Buffer */
|
||||||
|
mfc0 t0, CP0_PRID
|
||||||
|
andi t0, (PRID_IMP_MASK | PRID_REV_MASK)
|
||||||
|
slti t0, (PRID_IMP_LOONGSON_64 | PRID_REV_LOONGSON3A_R2)
|
||||||
|
bnez t0, 1f
|
||||||
mfc0 t0, CP0_CONFIG6
|
mfc0 t0, CP0_CONFIG6
|
||||||
or t0, 0x100
|
or t0, 0x100
|
||||||
mtc0 t0, CP0_CONFIG6
|
mtc0 t0, CP0_CONFIG6
|
||||||
#endif
|
1:
|
||||||
_ehb
|
_ehb
|
||||||
.set pop
|
.set pop
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2287,13 +2287,14 @@ do { \
|
||||||
_write_32bit_cp1_register(dest, val, )
|
_write_32bit_cp1_register(dest, val, )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_AS_DSP
|
#ifdef TOOLCHAIN_SUPPORTS_DSP
|
||||||
#define rddsp(mask) \
|
#define rddsp(mask) \
|
||||||
({ \
|
({ \
|
||||||
unsigned int __dspctl; \
|
unsigned int __dspctl; \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" rddsp %0, %x1 \n" \
|
" rddsp %0, %x1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2306,6 +2307,7 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" wrdsp %0, %x1 \n" \
|
" wrdsp %0, %x1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2318,6 +2320,7 @@ do { \
|
||||||
long mflo0; \
|
long mflo0; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mflo %0, $ac0 \n" \
|
" mflo %0, $ac0 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2330,6 +2333,7 @@ do { \
|
||||||
long mflo1; \
|
long mflo1; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mflo %0, $ac1 \n" \
|
" mflo %0, $ac1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2342,6 +2346,7 @@ do { \
|
||||||
long mflo2; \
|
long mflo2; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mflo %0, $ac2 \n" \
|
" mflo %0, $ac2 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2354,6 +2359,7 @@ do { \
|
||||||
long mflo3; \
|
long mflo3; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mflo %0, $ac3 \n" \
|
" mflo %0, $ac3 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2366,6 +2372,7 @@ do { \
|
||||||
long mfhi0; \
|
long mfhi0; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mfhi %0, $ac0 \n" \
|
" mfhi %0, $ac0 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2378,6 +2385,7 @@ do { \
|
||||||
long mfhi1; \
|
long mfhi1; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mfhi %0, $ac1 \n" \
|
" mfhi %0, $ac1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2390,6 +2398,7 @@ do { \
|
||||||
long mfhi2; \
|
long mfhi2; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mfhi %0, $ac2 \n" \
|
" mfhi %0, $ac2 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2402,6 +2411,7 @@ do { \
|
||||||
long mfhi3; \
|
long mfhi3; \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mfhi %0, $ac3 \n" \
|
" mfhi %0, $ac3 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2414,6 +2424,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mtlo %0, $ac0 \n" \
|
" mtlo %0, $ac0 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2425,6 +2436,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mtlo %0, $ac1 \n" \
|
" mtlo %0, $ac1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2436,6 +2448,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mtlo %0, $ac2 \n" \
|
" mtlo %0, $ac2 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2447,6 +2460,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mtlo %0, $ac3 \n" \
|
" mtlo %0, $ac3 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2458,6 +2472,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mthi %0, $ac0 \n" \
|
" mthi %0, $ac0 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2469,6 +2484,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mthi %0, $ac1 \n" \
|
" mthi %0, $ac1 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2480,6 +2496,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mthi %0, $ac2 \n" \
|
" mthi %0, $ac2 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
@ -2491,6 +2508,7 @@ do { \
|
||||||
({ \
|
({ \
|
||||||
__asm__( \
|
__asm__( \
|
||||||
" .set push \n" \
|
" .set push \n" \
|
||||||
|
" .set " MIPS_ISA_LEVEL " \n" \
|
||||||
" .set dsp \n" \
|
" .set dsp \n" \
|
||||||
" mthi %0, $ac3 \n" \
|
" mthi %0, $ac3 \n" \
|
||||||
" .set pop \n" \
|
" .set pop \n" \
|
||||||
|
|
|
@ -48,58 +48,14 @@ extern void (*r4k_blast_icache)(void);
|
||||||
: \
|
: \
|
||||||
: "i" (op), "R" (*(unsigned char *)(addr)))
|
: "i" (op), "R" (*(unsigned char *)(addr)))
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_MT
|
|
||||||
|
|
||||||
#define __iflush_prologue \
|
|
||||||
unsigned long redundance; \
|
|
||||||
extern int mt_n_iflushes; \
|
|
||||||
for (redundance = 0; redundance < mt_n_iflushes; redundance++) {
|
|
||||||
|
|
||||||
#define __iflush_epilogue \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __dflush_prologue \
|
|
||||||
unsigned long redundance; \
|
|
||||||
extern int mt_n_dflushes; \
|
|
||||||
for (redundance = 0; redundance < mt_n_dflushes; redundance++) {
|
|
||||||
|
|
||||||
#define __dflush_epilogue \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __inv_dflush_prologue __dflush_prologue
|
|
||||||
#define __inv_dflush_epilogue __dflush_epilogue
|
|
||||||
#define __sflush_prologue {
|
|
||||||
#define __sflush_epilogue }
|
|
||||||
#define __inv_sflush_prologue __sflush_prologue
|
|
||||||
#define __inv_sflush_epilogue __sflush_epilogue
|
|
||||||
|
|
||||||
#else /* CONFIG_MIPS_MT */
|
|
||||||
|
|
||||||
#define __iflush_prologue {
|
|
||||||
#define __iflush_epilogue }
|
|
||||||
#define __dflush_prologue {
|
|
||||||
#define __dflush_epilogue }
|
|
||||||
#define __inv_dflush_prologue {
|
|
||||||
#define __inv_dflush_epilogue }
|
|
||||||
#define __sflush_prologue {
|
|
||||||
#define __sflush_epilogue }
|
|
||||||
#define __inv_sflush_prologue {
|
|
||||||
#define __inv_sflush_epilogue }
|
|
||||||
|
|
||||||
#endif /* CONFIG_MIPS_MT */
|
|
||||||
|
|
||||||
static inline void flush_icache_line_indexed(unsigned long addr)
|
static inline void flush_icache_line_indexed(unsigned long addr)
|
||||||
{
|
{
|
||||||
__iflush_prologue
|
|
||||||
cache_op(Index_Invalidate_I, addr);
|
cache_op(Index_Invalidate_I, addr);
|
||||||
__iflush_epilogue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_dcache_line_indexed(unsigned long addr)
|
static inline void flush_dcache_line_indexed(unsigned long addr)
|
||||||
{
|
{
|
||||||
__dflush_prologue
|
|
||||||
cache_op(Index_Writeback_Inv_D, addr);
|
cache_op(Index_Writeback_Inv_D, addr);
|
||||||
__dflush_epilogue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_scache_line_indexed(unsigned long addr)
|
static inline void flush_scache_line_indexed(unsigned long addr)
|
||||||
|
@ -109,7 +65,6 @@ static inline void flush_scache_line_indexed(unsigned long addr)
|
||||||
|
|
||||||
static inline void flush_icache_line(unsigned long addr)
|
static inline void flush_icache_line(unsigned long addr)
|
||||||
{
|
{
|
||||||
__iflush_prologue
|
|
||||||
switch (boot_cpu_type()) {
|
switch (boot_cpu_type()) {
|
||||||
case CPU_LOONGSON2:
|
case CPU_LOONGSON2:
|
||||||
cache_op(Hit_Invalidate_I_Loongson2, addr);
|
cache_op(Hit_Invalidate_I_Loongson2, addr);
|
||||||
|
@ -119,21 +74,16 @@ static inline void flush_icache_line(unsigned long addr)
|
||||||
cache_op(Hit_Invalidate_I, addr);
|
cache_op(Hit_Invalidate_I, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
__iflush_epilogue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_dcache_line(unsigned long addr)
|
static inline void flush_dcache_line(unsigned long addr)
|
||||||
{
|
{
|
||||||
__dflush_prologue
|
|
||||||
cache_op(Hit_Writeback_Inv_D, addr);
|
cache_op(Hit_Writeback_Inv_D, addr);
|
||||||
__dflush_epilogue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void invalidate_dcache_line(unsigned long addr)
|
static inline void invalidate_dcache_line(unsigned long addr)
|
||||||
{
|
{
|
||||||
__dflush_prologue
|
|
||||||
cache_op(Hit_Invalidate_D, addr);
|
cache_op(Hit_Invalidate_D, addr);
|
||||||
__dflush_epilogue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void invalidate_scache_line(unsigned long addr)
|
static inline void invalidate_scache_line(unsigned long addr)
|
||||||
|
@ -586,13 +536,9 @@ static inline void extra##blast_##pfx##cache##lsize(void) \
|
||||||
current_cpu_data.desc.waybit; \
|
current_cpu_data.desc.waybit; \
|
||||||
unsigned long ws, addr; \
|
unsigned long ws, addr; \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
for (ws = 0; ws < ws_end; ws += ws_inc) \
|
for (ws = 0; ws < ws_end; ws += ws_inc) \
|
||||||
for (addr = start; addr < end; addr += lsize * 32) \
|
for (addr = start; addr < end; addr += lsize * 32) \
|
||||||
cache##lsize##_unroll32(addr|ws, indexop); \
|
cache##lsize##_unroll32(addr|ws, indexop); \
|
||||||
\
|
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
|
static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
|
||||||
|
@ -600,14 +546,10 @@ static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
|
||||||
unsigned long start = page; \
|
unsigned long start = page; \
|
||||||
unsigned long end = page + PAGE_SIZE; \
|
unsigned long end = page + PAGE_SIZE; \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
do { \
|
do { \
|
||||||
cache##lsize##_unroll32(start, hitop); \
|
cache##lsize##_unroll32(start, hitop); \
|
||||||
start += lsize * 32; \
|
start += lsize * 32; \
|
||||||
} while (start < end); \
|
} while (start < end); \
|
||||||
\
|
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
|
static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
|
||||||
|
@ -620,13 +562,9 @@ static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long
|
||||||
current_cpu_data.desc.waybit; \
|
current_cpu_data.desc.waybit; \
|
||||||
unsigned long ws, addr; \
|
unsigned long ws, addr; \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
for (ws = 0; ws < ws_end; ws += ws_inc) \
|
for (ws = 0; ws < ws_end; ws += ws_inc) \
|
||||||
for (addr = start; addr < end; addr += lsize * 32) \
|
for (addr = start; addr < end; addr += lsize * 32) \
|
||||||
cache##lsize##_unroll32(addr|ws, indexop); \
|
cache##lsize##_unroll32(addr|ws, indexop); \
|
||||||
\
|
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
|
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
|
||||||
|
@ -656,14 +594,10 @@ static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \
|
||||||
unsigned long start = page; \
|
unsigned long start = page; \
|
||||||
unsigned long end = page + PAGE_SIZE; \
|
unsigned long end = page + PAGE_SIZE; \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
do { \
|
do { \
|
||||||
cache##lsize##_unroll32_user(start, hitop); \
|
cache##lsize##_unroll32_user(start, hitop); \
|
||||||
start += lsize * 32; \
|
start += lsize * 32; \
|
||||||
} while (start < end); \
|
} while (start < end); \
|
||||||
\
|
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__BUILD_BLAST_USER_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D,
|
__BUILD_BLAST_USER_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D,
|
||||||
|
@ -685,16 +619,12 @@ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start,
|
||||||
unsigned long addr = start & ~(lsize - 1); \
|
unsigned long addr = start & ~(lsize - 1); \
|
||||||
unsigned long aend = (end - 1) & ~(lsize - 1); \
|
unsigned long aend = (end - 1) & ~(lsize - 1); \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
while (1) { \
|
while (1) { \
|
||||||
prot##cache_op(hitop, addr); \
|
prot##cache_op(hitop, addr); \
|
||||||
if (addr == aend) \
|
if (addr == aend) \
|
||||||
break; \
|
break; \
|
||||||
addr += lsize; \
|
addr += lsize; \
|
||||||
} \
|
} \
|
||||||
\
|
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_EVA
|
#ifndef CONFIG_EVA
|
||||||
|
@ -712,8 +642,6 @@ static inline void protected_blast_##pfx##cache##_range(unsigned long start,\
|
||||||
unsigned long addr = start & ~(lsize - 1); \
|
unsigned long addr = start & ~(lsize - 1); \
|
||||||
unsigned long aend = (end - 1) & ~(lsize - 1); \
|
unsigned long aend = (end - 1) & ~(lsize - 1); \
|
||||||
\
|
\
|
||||||
__##pfx##flush_prologue \
|
|
||||||
\
|
|
||||||
if (!uaccess_kernel()) { \
|
if (!uaccess_kernel()) { \
|
||||||
while (1) { \
|
while (1) { \
|
||||||
protected_cachee_op(hitop, addr); \
|
protected_cachee_op(hitop, addr); \
|
||||||
|
@ -730,7 +658,6 @@ static inline void protected_blast_##pfx##cache##_range(unsigned long start,\
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
__##pfx##flush_epilogue \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__BUILD_PROT_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D)
|
__BUILD_PROT_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D)
|
||||||
|
|
|
@ -33,6 +33,9 @@ struct plat_smp_ops {
|
||||||
int (*cpu_disable)(void);
|
int (*cpu_disable)(void);
|
||||||
void (*cpu_die)(unsigned int cpu);
|
void (*cpu_die)(unsigned int cpu);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
void (*kexec_nonboot_cpu)(void);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void register_smp_ops(const struct plat_smp_ops *ops);
|
extern void register_smp_ops(const struct plat_smp_ops *ops);
|
||||||
|
|
|
@ -91,6 +91,22 @@ static inline void __cpu_die(unsigned int cpu)
|
||||||
extern void play_dead(void);
|
extern void play_dead(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
static inline void kexec_nonboot_cpu(void)
|
||||||
|
{
|
||||||
|
extern const struct plat_smp_ops *mp_ops; /* private */
|
||||||
|
|
||||||
|
return mp_ops->kexec_nonboot_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *kexec_nonboot_cpu_func(void)
|
||||||
|
{
|
||||||
|
extern const struct plat_smp_ops *mp_ops; /* private */
|
||||||
|
|
||||||
|
return mp_ops->kexec_nonboot_cpu;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function will set up the necessary IPIs for Linux to communicate
|
* This function will set up the necessary IPIs for Linux to communicate
|
||||||
* with the CPUs in mask.
|
* with the CPUs in mask.
|
||||||
|
|
|
@ -113,22 +113,4 @@ obj-$(CONFIG_MIPS_CPC) += mips-cpc.o
|
||||||
obj-$(CONFIG_CPU_PM) += pm.o
|
obj-$(CONFIG_CPU_PM) += pm.o
|
||||||
obj-$(CONFIG_MIPS_CPS_PM) += pm-cps.o
|
obj-$(CONFIG_MIPS_CPS_PM) += pm-cps.o
|
||||||
|
|
||||||
#
|
|
||||||
# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not
|
|
||||||
# safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches
|
|
||||||
# here because the compiler may use DSP ASE instructions (such as lwx) in
|
|
||||||
# code paths where we cannot check that the CPU we are running on supports it.
|
|
||||||
# Proper abstraction using HAVE_AS_DSP and macros is done in
|
|
||||||
# arch/mips/include/asm/mipsregs.h.
|
|
||||||
#
|
|
||||||
ifeq ($(CONFIG_CPU_MIPSR2), y)
|
|
||||||
CFLAGS_DSP = -DHAVE_AS_DSP
|
|
||||||
|
|
||||||
CFLAGS_signal.o = $(CFLAGS_DSP)
|
|
||||||
CFLAGS_signal32.o = $(CFLAGS_DSP)
|
|
||||||
CFLAGS_process.o = $(CFLAGS_DSP)
|
|
||||||
CFLAGS_branch.o = $(CFLAGS_DSP)
|
|
||||||
CFLAGS_ptrace.o = $(CFLAGS_DSP)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
|
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
|
||||||
|
|
|
@ -36,6 +36,9 @@ static void crash_shutdown_secondary(void *passed_regs)
|
||||||
if (!cpu_online(cpu))
|
if (!cpu_online(cpu))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* We won't be sent IPIs any more. */
|
||||||
|
set_cpu_online(cpu, false);
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
if (!cpumask_test_cpu(cpu, &cpus_in_crash))
|
if (!cpumask_test_cpu(cpu, &cpus_in_crash))
|
||||||
crash_save_cpu(regs, cpu);
|
crash_save_cpu(regs, cpu);
|
||||||
|
@ -43,7 +46,9 @@ static void crash_shutdown_secondary(void *passed_regs)
|
||||||
|
|
||||||
while (!atomic_read(&kexec_ready_to_reboot))
|
while (!atomic_read(&kexec_ready_to_reboot))
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
relocated_kexec_smp_wait(NULL);
|
|
||||||
|
kexec_reboot();
|
||||||
|
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ EXPORT(_stext)
|
||||||
*/
|
*/
|
||||||
FEXPORT(__kernel_entry)
|
FEXPORT(__kernel_entry)
|
||||||
j kernel_entry
|
j kernel_entry
|
||||||
#endif
|
#endif /* CONFIG_BOOT_RAW */
|
||||||
|
|
||||||
__REF
|
__REF
|
||||||
|
|
||||||
|
@ -94,24 +94,26 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
|
||||||
0:
|
0:
|
||||||
|
|
||||||
#ifdef CONFIG_USE_OF
|
#ifdef CONFIG_USE_OF
|
||||||
#ifdef CONFIG_MIPS_RAW_APPENDED_DTB
|
#if defined(CONFIG_MIPS_RAW_APPENDED_DTB) || \
|
||||||
|
defined(CONFIG_MIPS_ELF_APPENDED_DTB)
|
||||||
|
|
||||||
PTR_LA t2, __appended_dtb
|
PTR_LA t2, __appended_dtb
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||||
li t1, 0xd00dfeed
|
li t1, 0xd00dfeed
|
||||||
#else
|
#else /* !CONFIG_CPU_BIG_ENDIAN */
|
||||||
li t1, 0xedfe0dd0
|
li t1, 0xedfe0dd0
|
||||||
#endif
|
#endif /* !CONFIG_CPU_BIG_ENDIAN */
|
||||||
lw t0, (t2)
|
lw t0, (t2)
|
||||||
beq t0, t1, dtb_found
|
beq t0, t1, dtb_found
|
||||||
#endif
|
#endif /* CONFIG_MIPS_RAW_APPENDED_DTB || CONFIG_MIPS_ELF_APPENDED_DTB */
|
||||||
li t1, -2
|
li t1, -2
|
||||||
move t2, a1
|
move t2, a1
|
||||||
beq a0, t1, dtb_found
|
beq a0, t1, dtb_found
|
||||||
|
|
||||||
li t2, 0
|
li t2, 0
|
||||||
dtb_found:
|
dtb_found:
|
||||||
#endif
|
#endif /* CONFIG_USE_OF */
|
||||||
PTR_LA t0, __bss_start # clear .bss
|
PTR_LA t0, __bss_start # clear .bss
|
||||||
LONG_S zero, (t0)
|
LONG_S zero, (t0)
|
||||||
PTR_LA t1, __bss_stop - LONGSIZE
|
PTR_LA t1, __bss_stop - LONGSIZE
|
||||||
|
@ -156,9 +158,9 @@ dtb_found:
|
||||||
* newly sync'd icache.
|
* newly sync'd icache.
|
||||||
*/
|
*/
|
||||||
jr.hb v0
|
jr.hb v0
|
||||||
#else
|
#else /* !CONFIG_RELOCATABLE */
|
||||||
j start_kernel
|
j start_kernel
|
||||||
#endif
|
#endif /* !CONFIG_RELOCATABLE */
|
||||||
END(kernel_entry)
|
END(kernel_entry)
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <linux/kexec.h>
|
#include <linux/kexec.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/libfdt.h>
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
@ -19,15 +20,18 @@ extern const size_t relocate_new_kernel_size;
|
||||||
extern unsigned long kexec_start_address;
|
extern unsigned long kexec_start_address;
|
||||||
extern unsigned long kexec_indirection_page;
|
extern unsigned long kexec_indirection_page;
|
||||||
|
|
||||||
int (*_machine_kexec_prepare)(struct kimage *) = NULL;
|
static unsigned long reboot_code_buffer;
|
||||||
void (*_machine_kexec_shutdown)(void) = NULL;
|
|
||||||
void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
void (*relocated_kexec_smp_wait) (void *);
|
static void (*relocated_kexec_smp_wait)(void *);
|
||||||
|
|
||||||
atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
|
atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
|
||||||
void (*_crash_smp_send_stop)(void) = NULL;
|
void (*_crash_smp_send_stop)(void) = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void (*_machine_kexec_shutdown)(void) = NULL;
|
||||||
|
void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
|
||||||
|
|
||||||
static void kexec_image_info(const struct kimage *kimage)
|
static void kexec_image_info(const struct kimage *kimage)
|
||||||
{
|
{
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
@ -48,13 +52,59 @@ static void kexec_image_info(const struct kimage *kimage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_UHI_BOOT
|
||||||
|
|
||||||
|
static int uhi_machine_kexec_prepare(struct kimage *kimage)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case DTB file is not passed to the new kernel, a flat device
|
||||||
|
* tree will be created by kexec tool. It holds modified command
|
||||||
|
* line for the new kernel.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < kimage->nr_segments; i++) {
|
||||||
|
struct fdt_header fdt;
|
||||||
|
|
||||||
|
if (kimage->segment[i].memsz <= sizeof(fdt))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (copy_from_user(&fdt, kimage->segment[i].buf, sizeof(fdt)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fdt_check_header(&fdt))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
kexec_args[0] = -2;
|
||||||
|
kexec_args[1] = (unsigned long)
|
||||||
|
phys_to_virt((unsigned long)kimage->segment[i].mem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int (*_machine_kexec_prepare)(struct kimage *) = uhi_machine_kexec_prepare;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int (*_machine_kexec_prepare)(struct kimage *) = NULL;
|
||||||
|
|
||||||
|
#endif /* CONFIG_UHI_BOOT */
|
||||||
|
|
||||||
int
|
int
|
||||||
machine_kexec_prepare(struct kimage *kimage)
|
machine_kexec_prepare(struct kimage *kimage)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
if (!kexec_nonboot_cpu_func())
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
kexec_image_info(kimage);
|
kexec_image_info(kimage);
|
||||||
|
|
||||||
if (_machine_kexec_prepare)
|
if (_machine_kexec_prepare)
|
||||||
return _machine_kexec_prepare(kimage);
|
return _machine_kexec_prepare(kimage);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +113,41 @@ machine_kexec_cleanup(struct kimage *kimage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
static void kexec_shutdown_secondary(void *param)
|
||||||
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
if (!cpu_online(cpu))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We won't be sent IPIs any more. */
|
||||||
|
set_cpu_online(cpu, false);
|
||||||
|
|
||||||
|
local_irq_disable();
|
||||||
|
while (!atomic_read(&kexec_ready_to_reboot))
|
||||||
|
cpu_relax();
|
||||||
|
|
||||||
|
kexec_reboot();
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
machine_shutdown(void)
|
machine_shutdown(void)
|
||||||
{
|
{
|
||||||
if (_machine_kexec_shutdown)
|
if (_machine_kexec_shutdown)
|
||||||
_machine_kexec_shutdown();
|
_machine_kexec_shutdown();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
smp_call_function(kexec_shutdown_secondary, NULL, 0);
|
||||||
|
|
||||||
|
while (num_online_cpus() > 1) {
|
||||||
|
cpu_relax();
|
||||||
|
mdelay(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -79,12 +159,57 @@ machine_crash_shutdown(struct pt_regs *regs)
|
||||||
default_machine_crash_shutdown(regs);
|
default_machine_crash_shutdown(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*noretfun_t)(void) __noreturn;
|
#ifdef CONFIG_SMP
|
||||||
|
void kexec_nonboot_cpu_jump(void)
|
||||||
|
{
|
||||||
|
local_flush_icache_range((unsigned long)relocated_kexec_smp_wait,
|
||||||
|
reboot_code_buffer + relocate_new_kernel_size);
|
||||||
|
|
||||||
|
relocated_kexec_smp_wait(NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void kexec_reboot(void)
|
||||||
|
{
|
||||||
|
void (*do_kexec)(void) __noreturn;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We know we were online, and there will be no incoming IPIs at
|
||||||
|
* this point. Mark online again before rebooting so that the crash
|
||||||
|
* analysis tool will see us correctly.
|
||||||
|
*/
|
||||||
|
set_cpu_online(smp_processor_id(), true);
|
||||||
|
|
||||||
|
/* Ensure remote CPUs observe that we're online before rebooting. */
|
||||||
|
smp_mb__after_atomic();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
if (smp_processor_id() > 0) {
|
||||||
|
/*
|
||||||
|
* Instead of cpu_relax() or wait, this is needed for kexec
|
||||||
|
* smp reboot. Kdump usually doesn't require an smp new
|
||||||
|
* kernel, but kexec may do.
|
||||||
|
*/
|
||||||
|
kexec_nonboot_cpu();
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we get correct instructions written by the
|
||||||
|
* machine_kexec() CPU.
|
||||||
|
*/
|
||||||
|
local_flush_icache_range(reboot_code_buffer,
|
||||||
|
reboot_code_buffer + relocate_new_kernel_size);
|
||||||
|
|
||||||
|
do_kexec = (void *)reboot_code_buffer;
|
||||||
|
do_kexec();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
machine_kexec(struct kimage *image)
|
machine_kexec(struct kimage *image)
|
||||||
{
|
{
|
||||||
unsigned long reboot_code_buffer;
|
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
unsigned long *ptr;
|
unsigned long *ptr;
|
||||||
|
|
||||||
|
@ -118,6 +243,9 @@ machine_kexec(struct kimage *image)
|
||||||
*ptr = (unsigned long) phys_to_virt(*ptr);
|
*ptr = (unsigned long) phys_to_virt(*ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark offline BEFORE disabling local irq. */
|
||||||
|
set_cpu_online(smp_processor_id(), false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we do not want to be bothered.
|
* we do not want to be bothered.
|
||||||
*/
|
*/
|
||||||
|
@ -125,6 +253,7 @@ machine_kexec(struct kimage *image)
|
||||||
|
|
||||||
printk("Will call new kernel at %08lx\n", image->start);
|
printk("Will call new kernel at %08lx\n", image->start);
|
||||||
printk("Bye ...\n");
|
printk("Bye ...\n");
|
||||||
|
/* Make reboot code buffer available to the boot CPU. */
|
||||||
__flush_cache_all();
|
__flush_cache_all();
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* All secondary cpus now may jump to kexec_wait cycle */
|
/* All secondary cpus now may jump to kexec_wait cycle */
|
||||||
|
@ -133,5 +262,5 @@ machine_kexec(struct kimage *image)
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
atomic_set(&kexec_ready_to_reboot, 1);
|
atomic_set(&kexec_ready_to_reboot, 1);
|
||||||
#endif
|
#endif
|
||||||
((noretfun_t) reboot_code_buffer)();
|
kexec_reboot();
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,40 +154,6 @@ static int __init config7_set(char *str)
|
||||||
}
|
}
|
||||||
__setup("config7=", config7_set);
|
__setup("config7=", config7_set);
|
||||||
|
|
||||||
/* Experimental cache flush control parameters that should go away some day */
|
|
||||||
int mt_protiflush;
|
|
||||||
int mt_protdflush;
|
|
||||||
int mt_n_iflushes = 1;
|
|
||||||
int mt_n_dflushes = 1;
|
|
||||||
|
|
||||||
static int __init set_protiflush(char *s)
|
|
||||||
{
|
|
||||||
mt_protiflush = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("protiflush", set_protiflush);
|
|
||||||
|
|
||||||
static int __init set_protdflush(char *s)
|
|
||||||
{
|
|
||||||
mt_protdflush = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("protdflush", set_protdflush);
|
|
||||||
|
|
||||||
static int __init niflush(char *s)
|
|
||||||
{
|
|
||||||
get_option(&s, &mt_n_iflushes);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("niflush=", niflush);
|
|
||||||
|
|
||||||
static int __init ndflush(char *s)
|
|
||||||
{
|
|
||||||
get_option(&s, &mt_n_dflushes);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("ndflush=", ndflush);
|
|
||||||
|
|
||||||
static unsigned int itc_base;
|
static unsigned int itc_base;
|
||||||
|
|
||||||
static int __init set_itc_base(char *str)
|
static int __init set_itc_base(char *str)
|
||||||
|
@ -232,16 +198,6 @@ void mips_mt_set_cpuoptions(void)
|
||||||
printk("Config7: 0x%08x\n", read_c0_config7());
|
printk("Config7: 0x%08x\n", read_c0_config7());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report Cache management debug options */
|
|
||||||
if (mt_protiflush)
|
|
||||||
printk("I-cache flushes single-threaded\n");
|
|
||||||
if (mt_protdflush)
|
|
||||||
printk("D-cache flushes single-threaded\n");
|
|
||||||
if (mt_n_iflushes != 1)
|
|
||||||
printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes);
|
|
||||||
if (mt_n_dflushes != 1)
|
|
||||||
printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes);
|
|
||||||
|
|
||||||
if (itc_base != 0) {
|
if (itc_base != 0) {
|
||||||
/*
|
/*
|
||||||
* Configure ITC mapping. This code is very
|
* Configure ITC mapping. This code is very
|
||||||
|
@ -283,21 +239,6 @@ void mips_mt_set_cpuoptions(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Function to protect cache flushes from concurrent execution
|
|
||||||
* depends on MP software model chosen.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void mt_cflush_lockdown(void)
|
|
||||||
{
|
|
||||||
/* FILL IN VSMP and AP/SP VERSIONS HERE */
|
|
||||||
}
|
|
||||||
|
|
||||||
void mt_cflush_release(void)
|
|
||||||
{
|
|
||||||
/* FILL IN VSMP and AP/SP VERSIONS HERE */
|
|
||||||
}
|
|
||||||
|
|
||||||
struct class *mt_class;
|
struct class *mt_class;
|
||||||
|
|
||||||
static int __init mt_init(void)
|
static int __init mt_init(void)
|
||||||
|
|
|
@ -146,7 +146,7 @@ int __init do_relocations(void *kbase_old, void *kbase_new, long offset)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
type = (*r >> 24) & 0xff;
|
type = (*r >> 24) & 0xff;
|
||||||
loc_orig = (void *)(kbase_old + ((*r & 0x00ffffff) << 2));
|
loc_orig = kbase_old + ((*r & 0x00ffffff) << 2);
|
||||||
loc_new = RELOCATED(loc_orig);
|
loc_new = RELOCATED(loc_orig);
|
||||||
|
|
||||||
if (reloc_handlers_rel[type] == NULL) {
|
if (reloc_handlers_rel[type] == NULL) {
|
||||||
|
|
|
@ -333,7 +333,7 @@ static void __init finalize_initrd(void)
|
||||||
|
|
||||||
maybe_bswap_initrd();
|
maybe_bswap_initrd();
|
||||||
|
|
||||||
reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
|
memblock_reserve(__pa(initrd_start), size);
|
||||||
initrd_below_start_ok = 1;
|
initrd_below_start_ok = 1;
|
||||||
|
|
||||||
pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n",
|
pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n",
|
||||||
|
@ -370,20 +370,10 @@ static void __init bootmem_init(void)
|
||||||
|
|
||||||
#else /* !CONFIG_SGI_IP27 */
|
#else /* !CONFIG_SGI_IP27 */
|
||||||
|
|
||||||
static unsigned long __init bootmap_bytes(unsigned long pages)
|
|
||||||
{
|
|
||||||
unsigned long bytes = DIV_ROUND_UP(pages, 8);
|
|
||||||
|
|
||||||
return ALIGN(bytes, sizeof(long));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init bootmem_init(void)
|
static void __init bootmem_init(void)
|
||||||
{
|
{
|
||||||
unsigned long reserved_end;
|
unsigned long reserved_end;
|
||||||
unsigned long mapstart = ~0UL;
|
|
||||||
unsigned long bootmap_size;
|
|
||||||
phys_addr_t ramstart = PHYS_ADDR_MAX;
|
phys_addr_t ramstart = PHYS_ADDR_MAX;
|
||||||
bool bootmap_valid = false;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -395,6 +385,8 @@ static void __init bootmem_init(void)
|
||||||
init_initrd();
|
init_initrd();
|
||||||
reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
|
reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
|
||||||
|
|
||||||
|
memblock_reserve(PHYS_OFFSET, reserved_end << PAGE_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* max_low_pfn is not a number of pages. The number of pages
|
* max_low_pfn is not a number of pages. The number of pages
|
||||||
* of the system is given by 'max_low_pfn - min_low_pfn'.
|
* of the system is given by 'max_low_pfn - min_low_pfn'.
|
||||||
|
@ -442,9 +434,6 @@ static void __init bootmem_init(void)
|
||||||
if (initrd_end && end <= (unsigned long)PFN_UP(__pa(initrd_end)))
|
if (initrd_end && end <= (unsigned long)PFN_UP(__pa(initrd_end)))
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if (start >= mapstart)
|
|
||||||
continue;
|
|
||||||
mapstart = max(reserved_end, start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_low_pfn >= max_low_pfn)
|
if (min_low_pfn >= max_low_pfn)
|
||||||
|
@ -456,9 +445,11 @@ static void __init bootmem_init(void)
|
||||||
/*
|
/*
|
||||||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||||
*/
|
*/
|
||||||
if (ramstart > PHYS_OFFSET)
|
if (ramstart > PHYS_OFFSET) {
|
||||||
add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
|
add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
|
||||||
BOOT_MEM_RESERVED);
|
BOOT_MEM_RESERVED);
|
||||||
|
memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
if (min_low_pfn > ARCH_PFN_OFFSET) {
|
if (min_low_pfn > ARCH_PFN_OFFSET) {
|
||||||
pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
|
pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
|
||||||
|
@ -483,52 +474,6 @@ static void __init bootmem_init(void)
|
||||||
max_low_pfn = PFN_DOWN(HIGHMEM_START);
|
max_low_pfn = PFN_DOWN(HIGHMEM_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
|
||||||
/*
|
|
||||||
* mapstart should be after initrd_end
|
|
||||||
*/
|
|
||||||
if (initrd_end)
|
|
||||||
mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check that mapstart doesn't overlap with any of
|
|
||||||
* memory regions that have been reserved through eg. DTB
|
|
||||||
*/
|
|
||||||
bootmap_size = bootmap_bytes(max_low_pfn - min_low_pfn);
|
|
||||||
|
|
||||||
bootmap_valid = memory_region_available(PFN_PHYS(mapstart),
|
|
||||||
bootmap_size);
|
|
||||||
for (i = 0; i < boot_mem_map.nr_map && !bootmap_valid; i++) {
|
|
||||||
unsigned long mapstart_addr;
|
|
||||||
|
|
||||||
switch (boot_mem_map.map[i].type) {
|
|
||||||
case BOOT_MEM_RESERVED:
|
|
||||||
mapstart_addr = PFN_ALIGN(boot_mem_map.map[i].addr +
|
|
||||||
boot_mem_map.map[i].size);
|
|
||||||
if (PHYS_PFN(mapstart_addr) < mapstart)
|
|
||||||
break;
|
|
||||||
|
|
||||||
bootmap_valid = memory_region_available(mapstart_addr,
|
|
||||||
bootmap_size);
|
|
||||||
if (bootmap_valid)
|
|
||||||
mapstart = PHYS_PFN(mapstart_addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bootmap_valid)
|
|
||||||
panic("No memory area to place a bootmap bitmap");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the boot-time allocator with low memory only.
|
|
||||||
*/
|
|
||||||
if (bootmap_size != init_bootmem_node(NODE_DATA(0), mapstart,
|
|
||||||
min_low_pfn, max_low_pfn))
|
|
||||||
panic("Unexpected memory size required for bootmap");
|
|
||||||
|
|
||||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||||
unsigned long start, end;
|
unsigned long start, end;
|
||||||
|
|
||||||
|
@ -577,9 +522,9 @@ static void __init bootmem_init(void)
|
||||||
default:
|
default:
|
||||||
/* Not usable memory */
|
/* Not usable memory */
|
||||||
if (start > min_low_pfn && end < max_low_pfn)
|
if (start > min_low_pfn && end < max_low_pfn)
|
||||||
reserve_bootmem(boot_mem_map.map[i].addr,
|
memblock_reserve(boot_mem_map.map[i].addr,
|
||||||
boot_mem_map.map[i].size,
|
boot_mem_map.map[i].size);
|
||||||
BOOTMEM_DEFAULT);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,15 +547,9 @@ static void __init bootmem_init(void)
|
||||||
size = end - start;
|
size = end - start;
|
||||||
|
|
||||||
/* Register lowmem ranges */
|
/* Register lowmem ranges */
|
||||||
free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT);
|
|
||||||
memory_present(0, start, end);
|
memory_present(0, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Reserve the bootmap memory.
|
|
||||||
*/
|
|
||||||
reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
|
|
||||||
|
|
||||||
#ifdef CONFIG_RELOCATABLE
|
#ifdef CONFIG_RELOCATABLE
|
||||||
/*
|
/*
|
||||||
* The kernel reserves all memory below its _end symbol as bootmem,
|
* The kernel reserves all memory below its _end symbol as bootmem,
|
||||||
|
@ -642,29 +581,6 @@ static void __init bootmem_init(void)
|
||||||
|
|
||||||
#endif /* CONFIG_SGI_IP27 */
|
#endif /* CONFIG_SGI_IP27 */
|
||||||
|
|
||||||
/*
|
|
||||||
* arch_mem_init - initialize memory management subsystem
|
|
||||||
*
|
|
||||||
* o plat_mem_setup() detects the memory configuration and will record detected
|
|
||||||
* memory areas using add_memory_region.
|
|
||||||
*
|
|
||||||
* At this stage the memory configuration of the system is known to the
|
|
||||||
* kernel but generic memory management system is still entirely uninitialized.
|
|
||||||
*
|
|
||||||
* o bootmem_init()
|
|
||||||
* o sparse_init()
|
|
||||||
* o paging_init()
|
|
||||||
* o dma_contiguous_reserve()
|
|
||||||
*
|
|
||||||
* At this stage the bootmem allocator is ready to use.
|
|
||||||
*
|
|
||||||
* NOTE: historically plat_mem_setup did the entire platform initialization.
|
|
||||||
* This was rather impractical because it meant plat_mem_setup had to
|
|
||||||
* get away without any kind of memory allocator. To keep old code from
|
|
||||||
* breaking plat_setup was just renamed to plat_mem_setup and a second platform
|
|
||||||
* initialization hook for anything else was introduced.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int usermem __initdata;
|
static int usermem __initdata;
|
||||||
|
|
||||||
static int __init early_parse_mem(char *p)
|
static int __init early_parse_mem(char *p)
|
||||||
|
@ -841,6 +757,28 @@ static void __init request_crashkernel(struct resource *res)
|
||||||
#define BUILTIN_EXTEND_WITH_PROM \
|
#define BUILTIN_EXTEND_WITH_PROM \
|
||||||
IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
|
IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* arch_mem_init - initialize memory management subsystem
|
||||||
|
*
|
||||||
|
* o plat_mem_setup() detects the memory configuration and will record detected
|
||||||
|
* memory areas using add_memory_region.
|
||||||
|
*
|
||||||
|
* At this stage the memory configuration of the system is known to the
|
||||||
|
* kernel but generic memory management system is still entirely uninitialized.
|
||||||
|
*
|
||||||
|
* o bootmem_init()
|
||||||
|
* o sparse_init()
|
||||||
|
* o paging_init()
|
||||||
|
* o dma_contiguous_reserve()
|
||||||
|
*
|
||||||
|
* At this stage the bootmem allocator is ready to use.
|
||||||
|
*
|
||||||
|
* NOTE: historically plat_mem_setup did the entire platform initialization.
|
||||||
|
* This was rather impractical because it meant plat_mem_setup had to
|
||||||
|
* get away without any kind of memory allocator. To keep old code from
|
||||||
|
* breaking plat_setup was just renamed to plat_mem_setup and a second platform
|
||||||
|
* initialization hook for anything else was introduced.
|
||||||
|
*/
|
||||||
static void __init arch_mem_init(char **cmdline_p)
|
static void __init arch_mem_init(char **cmdline_p)
|
||||||
{
|
{
|
||||||
struct memblock_region *reg;
|
struct memblock_region *reg;
|
||||||
|
@ -916,21 +854,29 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||||
early_init_fdt_scan_reserved_mem();
|
early_init_fdt_scan_reserved_mem();
|
||||||
|
|
||||||
bootmem_init();
|
bootmem_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevent memblock from allocating high memory.
|
||||||
|
* This cannot be done before max_low_pfn is detected, so up
|
||||||
|
* to this point is possible to only reserve physical memory
|
||||||
|
* with memblock_reserve; memblock_virt_alloc* can be used
|
||||||
|
* only after this point
|
||||||
|
*/
|
||||||
|
memblock_set_current_limit(PFN_PHYS(max_low_pfn));
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_VMCORE
|
#ifdef CONFIG_PROC_VMCORE
|
||||||
if (setup_elfcorehdr && setup_elfcorehdr_size) {
|
if (setup_elfcorehdr && setup_elfcorehdr_size) {
|
||||||
printk(KERN_INFO "kdump reserved memory at %lx-%lx\n",
|
printk(KERN_INFO "kdump reserved memory at %lx-%lx\n",
|
||||||
setup_elfcorehdr, setup_elfcorehdr_size);
|
setup_elfcorehdr, setup_elfcorehdr_size);
|
||||||
reserve_bootmem(setup_elfcorehdr, setup_elfcorehdr_size,
|
memblock_reserve(setup_elfcorehdr, setup_elfcorehdr_size);
|
||||||
BOOTMEM_DEFAULT);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mips_parse_crashkernel();
|
mips_parse_crashkernel();
|
||||||
#ifdef CONFIG_KEXEC
|
#ifdef CONFIG_KEXEC
|
||||||
if (crashk_res.start != crashk_res.end)
|
if (crashk_res.start != crashk_res.end)
|
||||||
reserve_bootmem(crashk_res.start,
|
memblock_reserve(crashk_res.start,
|
||||||
crashk_res.end - crashk_res.start + 1,
|
crashk_res.end - crashk_res.start + 1);
|
||||||
BOOTMEM_DEFAULT);
|
|
||||||
#endif
|
#endif
|
||||||
device_tree_init();
|
device_tree_init();
|
||||||
sparse_init();
|
sparse_init();
|
||||||
|
@ -940,7 +886,7 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||||
/* Tell bootmem about cma reserved memblock section */
|
/* Tell bootmem about cma reserved memblock section */
|
||||||
for_each_memblock(reserved, reg)
|
for_each_memblock(reserved, reg)
|
||||||
if (reg->size != 0)
|
if (reg->size != 0)
|
||||||
reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
|
memblock_reserve(reg->base, reg->size);
|
||||||
|
|
||||||
reserve_bootmem_region(__pa_symbol(&__nosave_begin),
|
reserve_bootmem_region(__pa_symbol(&__nosave_begin),
|
||||||
__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
|
__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
|
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
|
@ -423,6 +424,9 @@ const struct plat_smp_ops bmips43xx_smp_ops = {
|
||||||
.cpu_disable = bmips_cpu_disable,
|
.cpu_disable = bmips_cpu_disable,
|
||||||
.cpu_die = bmips_cpu_die,
|
.cpu_die = bmips_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct plat_smp_ops bmips5000_smp_ops = {
|
const struct plat_smp_ops bmips5000_smp_ops = {
|
||||||
|
@ -437,6 +441,9 @@ const struct plat_smp_ops bmips5000_smp_ops = {
|
||||||
.cpu_disable = bmips_cpu_disable,
|
.cpu_disable = bmips_cpu_disable,
|
||||||
.cpu_die = bmips_cpu_die,
|
.cpu_die = bmips_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
|
@ -398,6 +398,55 @@ static void cps_smp_finish(void)
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
|
||||||
|
|
||||||
|
enum cpu_death {
|
||||||
|
CPU_DEATH_HALT,
|
||||||
|
CPU_DEATH_POWER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void cps_shutdown_this_cpu(enum cpu_death death)
|
||||||
|
{
|
||||||
|
unsigned int cpu, core, vpe_id;
|
||||||
|
|
||||||
|
cpu = smp_processor_id();
|
||||||
|
core = cpu_core(&cpu_data[cpu]);
|
||||||
|
|
||||||
|
if (death == CPU_DEATH_HALT) {
|
||||||
|
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
|
||||||
|
|
||||||
|
pr_debug("Halting core %d VP%d\n", core, vpe_id);
|
||||||
|
if (cpu_has_mipsmt) {
|
||||||
|
/* Halt this TC */
|
||||||
|
write_c0_tchalt(TCHALT_H);
|
||||||
|
instruction_hazard();
|
||||||
|
} else if (cpu_has_vp) {
|
||||||
|
write_cpc_cl_vp_stop(1 << vpe_id);
|
||||||
|
|
||||||
|
/* Ensure that the VP_STOP register is written */
|
||||||
|
wmb();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_debug("Gating power to core %d\n", core);
|
||||||
|
/* Power down the core */
|
||||||
|
cps_pm_enter_state(CPS_PM_POWER_GATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
|
||||||
|
static void cps_kexec_nonboot_cpu(void)
|
||||||
|
{
|
||||||
|
if (cpu_has_mipsmt || cpu_has_vp)
|
||||||
|
cps_shutdown_this_cpu(CPU_DEATH_HALT);
|
||||||
|
else
|
||||||
|
cps_shutdown_this_cpu(CPU_DEATH_POWER);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_KEXEC */
|
||||||
|
|
||||||
|
#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
|
||||||
static int cps_cpu_disable(void)
|
static int cps_cpu_disable(void)
|
||||||
|
@ -421,19 +470,15 @@ static int cps_cpu_disable(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned cpu_death_sibling;
|
static unsigned cpu_death_sibling;
|
||||||
static enum {
|
static enum cpu_death cpu_death;
|
||||||
CPU_DEATH_HALT,
|
|
||||||
CPU_DEATH_POWER,
|
|
||||||
} cpu_death;
|
|
||||||
|
|
||||||
void play_dead(void)
|
void play_dead(void)
|
||||||
{
|
{
|
||||||
unsigned int cpu, core, vpe_id;
|
unsigned int cpu;
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
idle_task_exit();
|
idle_task_exit();
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
core = cpu_core(&cpu_data[cpu]);
|
|
||||||
cpu_death = CPU_DEATH_POWER;
|
cpu_death = CPU_DEATH_POWER;
|
||||||
|
|
||||||
pr_debug("CPU%d going offline\n", cpu);
|
pr_debug("CPU%d going offline\n", cpu);
|
||||||
|
@ -456,25 +501,7 @@ void play_dead(void)
|
||||||
/* This CPU has chosen its way out */
|
/* This CPU has chosen its way out */
|
||||||
(void)cpu_report_death();
|
(void)cpu_report_death();
|
||||||
|
|
||||||
if (cpu_death == CPU_DEATH_HALT) {
|
cps_shutdown_this_cpu(cpu_death);
|
||||||
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
|
|
||||||
|
|
||||||
pr_debug("Halting core %d VP%d\n", core, vpe_id);
|
|
||||||
if (cpu_has_mipsmt) {
|
|
||||||
/* Halt this TC */
|
|
||||||
write_c0_tchalt(TCHALT_H);
|
|
||||||
instruction_hazard();
|
|
||||||
} else if (cpu_has_vp) {
|
|
||||||
write_cpc_cl_vp_stop(1 << vpe_id);
|
|
||||||
|
|
||||||
/* Ensure that the VP_STOP register is written */
|
|
||||||
wmb();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pr_debug("Gating power to core %d\n", core);
|
|
||||||
/* Power down the core */
|
|
||||||
cps_pm_enter_state(CPS_PM_POWER_GATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This should never be reached */
|
/* This should never be reached */
|
||||||
panic("Failed to offline CPU %u", cpu);
|
panic("Failed to offline CPU %u", cpu);
|
||||||
|
@ -593,6 +620,9 @@ static const struct plat_smp_ops cps_smp_ops = {
|
||||||
.cpu_disable = cps_cpu_disable,
|
.cpu_disable = cps_cpu_disable,
|
||||||
.cpu_die = cps_cpu_die,
|
.cpu_die = cps_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = cps_kexec_nonboot_cpu,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
bool mips_cps_smp_in_use(void)
|
bool mips_cps_smp_in_use(void)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/memblock.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/kgdb.h>
|
#include <linux/kgdb.h>
|
||||||
|
@ -348,7 +349,7 @@ static void __show_regs(const struct pt_regs *regs)
|
||||||
*/
|
*/
|
||||||
void show_regs(struct pt_regs *regs)
|
void show_regs(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
__show_regs((struct pt_regs *)regs);
|
__show_regs(regs);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2260,8 +2261,10 @@ void __init trap_init(void)
|
||||||
unsigned long size = 0x200 + VECTORSPACING*64;
|
unsigned long size = 0x200 + VECTORSPACING*64;
|
||||||
phys_addr_t ebase_pa;
|
phys_addr_t ebase_pa;
|
||||||
|
|
||||||
|
memblock_set_bottom_up(true);
|
||||||
ebase = (unsigned long)
|
ebase = (unsigned long)
|
||||||
__alloc_bootmem(size, 1 << fls(size), 0);
|
__alloc_bootmem(size, 1 << fls(size), 0);
|
||||||
|
memblock_set_bottom_up(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to ensure ebase resides in KSeg0 if possible.
|
* Try to ensure ebase resides in KSeg0 if possible.
|
||||||
|
|
|
@ -130,7 +130,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _LoadW(addr, value, res, type) \
|
#define _LoadW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -151,8 +151,8 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has no lwl instruction */
|
/* For CPUs without lwl instruction */
|
||||||
#define _LoadW(addr, value, res, type) \
|
#define _LoadW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -186,7 +186,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
|
|
||||||
#define _LoadHWU(addr, value, res, type) \
|
#define _LoadHWU(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -212,7 +212,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _LoadWU(addr, value, res, type) \
|
#define _LoadWU(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -255,8 +255,8 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has not lwl and ldl instructions */
|
/* For CPUs without lwl and ldl instructions */
|
||||||
#define _LoadWU(addr, value, res, type) \
|
#define _LoadWU(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -339,7 +339,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
|
|
||||||
|
|
||||||
#define _StoreHW(addr, value, res, type) \
|
#define _StoreHW(addr, value, res, type) \
|
||||||
|
@ -365,7 +365,7 @@ do { \
|
||||||
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _StoreW(addr, value, res, type) \
|
#define _StoreW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -406,8 +406,7 @@ do { \
|
||||||
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has no swl and sdl instructions */
|
|
||||||
#define _StoreW(addr, value, res, type) \
|
#define _StoreW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -483,7 +482,7 @@ do { \
|
||||||
: "memory"); \
|
: "memory"); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
|
|
||||||
#else /* __BIG_ENDIAN */
|
#else /* __BIG_ENDIAN */
|
||||||
|
|
||||||
|
@ -509,7 +508,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _LoadW(addr, value, res, type) \
|
#define _LoadW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -530,8 +529,8 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has no lwl instruction */
|
/* For CPUs without lwl instruction */
|
||||||
#define _LoadW(addr, value, res, type) \
|
#define _LoadW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -565,7 +564,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
|
|
||||||
|
|
||||||
#define _LoadHWU(addr, value, res, type) \
|
#define _LoadHWU(addr, value, res, type) \
|
||||||
|
@ -592,7 +591,7 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _LoadWU(addr, value, res, type) \
|
#define _LoadWU(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -635,8 +634,8 @@ do { \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has not lwl and ldl instructions */
|
/* For CPUs without lwl and ldl instructions */
|
||||||
#define _LoadWU(addr, value, res, type) \
|
#define _LoadWU(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -718,7 +717,7 @@ do { \
|
||||||
: "=&r" (value), "=r" (res) \
|
: "=&r" (value), "=r" (res) \
|
||||||
: "r" (addr), "i" (-EFAULT)); \
|
: "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
|
|
||||||
#define _StoreHW(addr, value, res, type) \
|
#define _StoreHW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -743,7 +742,7 @@ do { \
|
||||||
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
#define _StoreW(addr, value, res, type) \
|
#define _StoreW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -784,8 +783,8 @@ do { \
|
||||||
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#else
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
/* MIPSR6 has no swl and sdl instructions */
|
/* For CPUs without swl and sdl instructions */
|
||||||
#define _StoreW(addr, value, res, type) \
|
#define _StoreW(addr, value, res, type) \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
|
@ -861,7 +860,7 @@ do { \
|
||||||
: "memory"); \
|
: "memory"); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
|
#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
|
||||||
|
|
|
@ -7,7 +7,7 @@ lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \
|
||||||
mips-atomic.o strncpy_user.o \
|
mips-atomic.o strncpy_user.o \
|
||||||
strnlen_user.o uncached.o
|
strnlen_user.o uncached.o
|
||||||
|
|
||||||
obj-y += iomap.o iomap_copy.o
|
obj-y += iomap_copy.o
|
||||||
obj-$(CONFIG_PCI) += iomap-pci.o
|
obj-$(CONFIG_PCI) += iomap-pci.o
|
||||||
lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y))
|
lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y))
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,3 @@ void __iomem *__pci_ioport_map(struct pci_dev *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PCI_DRIVERS_LEGACY */
|
#endif /* CONFIG_PCI_DRIVERS_LEGACY */
|
||||||
|
|
||||||
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
|
|
||||||
{
|
|
||||||
iounmap(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(pci_iounmap);
|
|
||||||
|
|
|
@ -1,227 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Implement the default iomap interfaces
|
|
||||||
*
|
|
||||||
* (C) Copyright 2004 Linus Torvalds
|
|
||||||
* (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
|
|
||||||
* (C) Copyright 2007 MIPS Technologies, Inc.
|
|
||||||
* written by Ralf Baechle <ralf@linux-mips.org>
|
|
||||||
*/
|
|
||||||
#include <linux/export.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read/write from/to an (offsettable) iomem cookie. It might be a PIO
|
|
||||||
* access or a MMIO access, these functions don't care. The info is
|
|
||||||
* encoded in the hardware mapping set up by the mapping functions
|
|
||||||
* (or the cookie itself, depending on implementation and hw).
|
|
||||||
*
|
|
||||||
* The generic routines don't assume any hardware mappings, and just
|
|
||||||
* encode the PIO/MMIO as part of the cookie. They coldly assume that
|
|
||||||
* the MMIO IO mappings are not in the low address range.
|
|
||||||
*
|
|
||||||
* Architectures for which this is not true can't use this generic
|
|
||||||
* implementation and should do their own copy.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PIO_MASK 0x0ffffUL
|
|
||||||
|
|
||||||
unsigned int ioread8(void __iomem *addr)
|
|
||||||
{
|
|
||||||
return readb(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread8);
|
|
||||||
|
|
||||||
unsigned int ioread16(void __iomem *addr)
|
|
||||||
{
|
|
||||||
return readw(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread16);
|
|
||||||
|
|
||||||
unsigned int ioread16be(void __iomem *addr)
|
|
||||||
{
|
|
||||||
return be16_to_cpu(__raw_readw(addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread16be);
|
|
||||||
|
|
||||||
unsigned int ioread32(void __iomem *addr)
|
|
||||||
{
|
|
||||||
return readl(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread32);
|
|
||||||
|
|
||||||
unsigned int ioread32be(void __iomem *addr)
|
|
||||||
{
|
|
||||||
return be32_to_cpu(__raw_readl(addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread32be);
|
|
||||||
|
|
||||||
void iowrite8(u8 val, void __iomem *addr)
|
|
||||||
{
|
|
||||||
writeb(val, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite8);
|
|
||||||
|
|
||||||
void iowrite16(u16 val, void __iomem *addr)
|
|
||||||
{
|
|
||||||
writew(val, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite16);
|
|
||||||
|
|
||||||
void iowrite16be(u16 val, void __iomem *addr)
|
|
||||||
{
|
|
||||||
__raw_writew(cpu_to_be16(val), addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite16be);
|
|
||||||
|
|
||||||
void iowrite32(u32 val, void __iomem *addr)
|
|
||||||
{
|
|
||||||
writel(val, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite32);
|
|
||||||
|
|
||||||
void iowrite32be(u32 val, void __iomem *addr)
|
|
||||||
{
|
|
||||||
__raw_writel(cpu_to_be32(val), addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite32be);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are the "repeat MMIO read/write" functions.
|
|
||||||
* Note the "__mem" accesses, since we want to convert
|
|
||||||
* to CPU byte order if the host bus happens to not match the
|
|
||||||
* endianness of PCI/ISA (see mach-generic/mangle-port.h).
|
|
||||||
*/
|
|
||||||
static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
u8 data = __mem_readb(addr);
|
|
||||||
*dst = data;
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
u16 data = __mem_readw(addr);
|
|
||||||
*dst = data;
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
u32 data = __mem_readl(addr);
|
|
||||||
*dst = data;
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
__mem_writeb(*src, addr);
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
__mem_writew(*src, addr);
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
|
|
||||||
{
|
|
||||||
while (--count >= 0) {
|
|
||||||
__mem_writel(*src, addr);
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_insb(addr, dst, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread8_rep);
|
|
||||||
|
|
||||||
void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_insw(addr, dst, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread16_rep);
|
|
||||||
|
|
||||||
void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_insl(addr, dst, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioread32_rep);
|
|
||||||
|
|
||||||
void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_outsb(addr, src, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite8_rep);
|
|
||||||
|
|
||||||
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_outsw(addr, src, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite16_rep);
|
|
||||||
|
|
||||||
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
mmio_outsl(addr, src, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(iowrite32_rep);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a virtual mapping cookie for an IO port range
|
|
||||||
*
|
|
||||||
* This uses the same mapping are as the in/out family which has to be setup
|
|
||||||
* by the platform initialization code.
|
|
||||||
*
|
|
||||||
* Just to make matters somewhat more interesting on MIPS systems with
|
|
||||||
* multiple host bridge each will have it's own ioport address space.
|
|
||||||
*/
|
|
||||||
static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
|
|
||||||
{
|
|
||||||
return (void __iomem *) (mips_io_port_base + port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __iomem *ioport_map(unsigned long port, unsigned int nr)
|
|
||||||
{
|
|
||||||
if (port > PIO_MASK)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return ioport_map_legacy(port, nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioport_map);
|
|
||||||
|
|
||||||
void ioport_unmap(void __iomem *addr)
|
|
||||||
{
|
|
||||||
/* Nothing to do */
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ioport_unmap);
|
|
|
@ -204,9 +204,10 @@
|
||||||
#define LOADB(reg, addr, handler) EXC(lb, LD_INSN, reg, addr, handler)
|
#define LOADB(reg, addr, handler) EXC(lb, LD_INSN, reg, addr, handler)
|
||||||
#define STOREB(reg, addr, handler) EXC(sb, ST_INSN, reg, addr, handler)
|
#define STOREB(reg, addr, handler) EXC(sb, ST_INSN, reg, addr, handler)
|
||||||
|
|
||||||
#define _PREF(hint, addr, type) \
|
#ifdef CONFIG_CPU_HAS_PREFETCH
|
||||||
|
# define _PREF(hint, addr, type) \
|
||||||
.if \mode == LEGACY_MODE; \
|
.if \mode == LEGACY_MODE; \
|
||||||
PREF(hint, addr); \
|
kernel_pref(hint, addr); \
|
||||||
.else; \
|
.else; \
|
||||||
.if ((\from == USEROP) && (type == SRC_PREFETCH)) || \
|
.if ((\from == USEROP) && (type == SRC_PREFETCH)) || \
|
||||||
((\to == USEROP) && (type == DST_PREFETCH)); \
|
((\to == USEROP) && (type == DST_PREFETCH)); \
|
||||||
|
@ -218,12 +219,15 @@
|
||||||
* used later on. Therefore use $v1. \
|
* used later on. Therefore use $v1. \
|
||||||
*/ \
|
*/ \
|
||||||
.set at=v1; \
|
.set at=v1; \
|
||||||
PREFE(hint, addr); \
|
user_pref(hint, addr); \
|
||||||
.set noat; \
|
.set noat; \
|
||||||
.else; \
|
.else; \
|
||||||
PREF(hint, addr); \
|
kernel_pref(hint, addr); \
|
||||||
.endif; \
|
.endif; \
|
||||||
.endif
|
.endif
|
||||||
|
#else
|
||||||
|
# define _PREF(hint, addr, type)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PREFS(hint, addr) _PREF(hint, addr, SRC_PREFETCH)
|
#define PREFS(hint, addr) _PREF(hint, addr, SRC_PREFETCH)
|
||||||
#define PREFD(hint, addr) _PREF(hint, addr, DST_PREFETCH)
|
#define PREFD(hint, addr) _PREF(hint, addr, DST_PREFETCH)
|
||||||
|
@ -297,7 +301,7 @@
|
||||||
and t0, src, ADDRMASK
|
and t0, src, ADDRMASK
|
||||||
PREFS( 0, 2*32(src) )
|
PREFS( 0, 2*32(src) )
|
||||||
PREFD( 1, 2*32(dst) )
|
PREFD( 1, 2*32(dst) )
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
bnez t1, .Ldst_unaligned\@
|
bnez t1, .Ldst_unaligned\@
|
||||||
nop
|
nop
|
||||||
bnez t0, .Lsrc_unaligned_dst_aligned\@
|
bnez t0, .Lsrc_unaligned_dst_aligned\@
|
||||||
|
@ -385,7 +389,7 @@
|
||||||
bne rem, len, 1b
|
bne rem, len, 1b
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
/*
|
/*
|
||||||
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
|
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
|
||||||
* A loop would do only a byte at a time with possible branch
|
* A loop would do only a byte at a time with possible branch
|
||||||
|
@ -487,7 +491,7 @@
|
||||||
bne len, rem, 1b
|
bne len, rem, 1b
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
#endif /* !CONFIG_CPU_MIPSR6 */
|
#endif /* CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
.Lcopy_bytes_checklen\@:
|
.Lcopy_bytes_checklen\@:
|
||||||
beqz len, .Ldone\@
|
beqz len, .Ldone\@
|
||||||
nop
|
nop
|
||||||
|
@ -516,7 +520,7 @@
|
||||||
jr ra
|
jr ra
|
||||||
nop
|
nop
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_MIPSR6
|
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
.Lcopy_unaligned_bytes\@:
|
.Lcopy_unaligned_bytes\@:
|
||||||
1:
|
1:
|
||||||
COPY_BYTE(0)
|
COPY_BYTE(0)
|
||||||
|
@ -530,7 +534,7 @@
|
||||||
ADD src, src, 8
|
ADD src, src, 8
|
||||||
b 1b
|
b 1b
|
||||||
ADD dst, dst, 8
|
ADD dst, dst, 8
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
.if __memcpy == 1
|
.if __memcpy == 1
|
||||||
END(memcpy)
|
END(memcpy)
|
||||||
.set __memcpy, 0
|
.set __memcpy, 0
|
||||||
|
|
|
@ -78,7 +78,6 @@
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.set noreorder
|
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -94,13 +93,16 @@
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
sltiu t0, a2, STORSIZE /* very small region? */
|
sltiu t0, a2, STORSIZE /* very small region? */
|
||||||
|
.set noreorder
|
||||||
bnez t0, .Lsmall_memset\@
|
bnez t0, .Lsmall_memset\@
|
||||||
andi t0, a0, STORMASK /* aligned? */
|
andi t0, a0, STORMASK /* aligned? */
|
||||||
|
.set reorder
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_MICROMIPS
|
#ifdef CONFIG_CPU_MICROMIPS
|
||||||
move t8, a1 /* used by 'swp' instruction */
|
move t8, a1 /* used by 'swp' instruction */
|
||||||
move t9, a1
|
move t9, a1
|
||||||
#endif
|
#endif
|
||||||
|
.set noreorder
|
||||||
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
|
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
|
||||||
beqz t0, 1f
|
beqz t0, 1f
|
||||||
PTR_SUBU t0, STORSIZE /* alignment in bytes */
|
PTR_SUBU t0, STORSIZE /* alignment in bytes */
|
||||||
|
@ -111,8 +113,9 @@
|
||||||
PTR_SUBU t0, AT /* alignment in bytes */
|
PTR_SUBU t0, AT /* alignment in bytes */
|
||||||
.set at
|
.set at
|
||||||
#endif
|
#endif
|
||||||
|
.set reorder
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
R10KCBARRIER(0(ra))
|
R10KCBARRIER(0(ra))
|
||||||
#ifdef __MIPSEB__
|
#ifdef __MIPSEB__
|
||||||
EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
|
EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
|
||||||
|
@ -122,11 +125,13 @@
|
||||||
PTR_SUBU a0, t0 /* long align ptr */
|
PTR_SUBU a0, t0 /* long align ptr */
|
||||||
PTR_ADDU a2, t0 /* correct size */
|
PTR_ADDU a2, t0 /* correct size */
|
||||||
|
|
||||||
#else /* CONFIG_CPU_MIPSR6 */
|
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
#define STORE_BYTE(N) \
|
#define STORE_BYTE(N) \
|
||||||
EX(sb, a1, N(a0), .Lbyte_fixup\@); \
|
EX(sb, a1, N(a0), .Lbyte_fixup\@); \
|
||||||
|
.set noreorder; \
|
||||||
beqz t0, 0f; \
|
beqz t0, 0f; \
|
||||||
PTR_ADDU t0, 1;
|
PTR_ADDU t0, 1; \
|
||||||
|
.set reorder;
|
||||||
|
|
||||||
PTR_ADDU a2, t0 /* correct size */
|
PTR_ADDU a2, t0 /* correct size */
|
||||||
PTR_ADDU t0, 1
|
PTR_ADDU t0, 1
|
||||||
|
@ -145,19 +150,17 @@
|
||||||
ori a0, STORMASK
|
ori a0, STORMASK
|
||||||
xori a0, STORMASK
|
xori a0, STORMASK
|
||||||
PTR_ADDIU a0, STORSIZE
|
PTR_ADDIU a0, STORSIZE
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
1: ori t1, a2, 0x3f /* # of full blocks */
|
1: ori t1, a2, 0x3f /* # of full blocks */
|
||||||
xori t1, 0x3f
|
xori t1, 0x3f
|
||||||
|
andi t0, a2, 0x40-STORSIZE
|
||||||
beqz t1, .Lmemset_partial\@ /* no block to fill */
|
beqz t1, .Lmemset_partial\@ /* no block to fill */
|
||||||
andi t0, a2, 0x40-STORSIZE
|
|
||||||
|
|
||||||
PTR_ADDU t1, a0 /* end address */
|
PTR_ADDU t1, a0 /* end address */
|
||||||
.set reorder
|
|
||||||
1: PTR_ADDIU a0, 64
|
1: PTR_ADDIU a0, 64
|
||||||
R10KCBARRIER(0(ra))
|
R10KCBARRIER(0(ra))
|
||||||
f_fill64 a0, -64, FILL64RG, .Lfwd_fixup\@, \mode
|
f_fill64 a0, -64, FILL64RG, .Lfwd_fixup\@, \mode
|
||||||
bne t1, a0, 1b
|
bne t1, a0, 1b
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
.Lmemset_partial\@:
|
.Lmemset_partial\@:
|
||||||
R10KCBARRIER(0(ra))
|
R10KCBARRIER(0(ra))
|
||||||
|
@ -173,20 +176,18 @@
|
||||||
PTR_SUBU t1, AT
|
PTR_SUBU t1, AT
|
||||||
.set at
|
.set at
|
||||||
#endif
|
#endif
|
||||||
|
PTR_ADDU a0, t0 /* dest ptr */
|
||||||
jr t1
|
jr t1
|
||||||
PTR_ADDU a0, t0 /* dest ptr */
|
|
||||||
|
|
||||||
.set push
|
|
||||||
.set noreorder
|
|
||||||
.set nomacro
|
|
||||||
/* ... but first do longs ... */
|
/* ... but first do longs ... */
|
||||||
f_fill64 a0, -64, FILL64RG, .Lpartial_fixup\@, \mode
|
f_fill64 a0, -64, FILL64RG, .Lpartial_fixup\@, \mode
|
||||||
2: .set pop
|
2: andi a2, STORMASK /* At most one long to go */
|
||||||
andi a2, STORMASK /* At most one long to go */
|
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
beqz a2, 1f
|
beqz a2, 1f
|
||||||
#ifndef CONFIG_CPU_MIPSR6
|
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
PTR_ADDU a0, a2 /* What's left */
|
PTR_ADDU a0, a2 /* What's left */
|
||||||
|
.set reorder
|
||||||
R10KCBARRIER(0(ra))
|
R10KCBARRIER(0(ra))
|
||||||
#ifdef __MIPSEB__
|
#ifdef __MIPSEB__
|
||||||
EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@)
|
EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@)
|
||||||
|
@ -195,6 +196,7 @@
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
PTR_SUBU t0, $0, a2
|
PTR_SUBU t0, $0, a2
|
||||||
|
.set reorder
|
||||||
move a2, zero /* No remaining longs */
|
move a2, zero /* No remaining longs */
|
||||||
PTR_ADDIU t0, 1
|
PTR_ADDIU t0, 1
|
||||||
STORE_BYTE(0)
|
STORE_BYTE(0)
|
||||||
|
@ -210,41 +212,42 @@
|
||||||
#endif
|
#endif
|
||||||
0:
|
0:
|
||||||
#endif
|
#endif
|
||||||
1: jr ra
|
1: move a2, zero
|
||||||
move a2, zero
|
jr ra
|
||||||
|
|
||||||
.Lsmall_memset\@:
|
.Lsmall_memset\@:
|
||||||
|
PTR_ADDU t1, a0, a2
|
||||||
beqz a2, 2f
|
beqz a2, 2f
|
||||||
PTR_ADDU t1, a0, a2
|
|
||||||
|
|
||||||
1: PTR_ADDIU a0, 1 /* fill bytewise */
|
1: PTR_ADDIU a0, 1 /* fill bytewise */
|
||||||
R10KCBARRIER(0(ra))
|
R10KCBARRIER(0(ra))
|
||||||
|
.set noreorder
|
||||||
bne t1, a0, 1b
|
bne t1, a0, 1b
|
||||||
EX(sb, a1, -1(a0), .Lsmall_fixup\@)
|
EX(sb, a1, -1(a0), .Lsmall_fixup\@)
|
||||||
|
.set reorder
|
||||||
|
|
||||||
2: jr ra /* done */
|
2: move a2, zero
|
||||||
move a2, zero
|
jr ra /* done */
|
||||||
.if __memset == 1
|
.if __memset == 1
|
||||||
END(memset)
|
END(memset)
|
||||||
.set __memset, 0
|
.set __memset, 0
|
||||||
.hidden __memset
|
.hidden __memset
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_MIPSR6
|
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||||
.Lbyte_fixup\@:
|
.Lbyte_fixup\@:
|
||||||
/*
|
/*
|
||||||
* unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1
|
* unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1
|
||||||
* a2 = a2 - t0 + 1
|
* a2 = a2 - t0 + 1
|
||||||
*/
|
*/
|
||||||
PTR_SUBU a2, t0
|
PTR_SUBU a2, t0
|
||||||
|
PTR_ADDIU a2, 1
|
||||||
jr ra
|
jr ra
|
||||||
PTR_ADDIU a2, 1
|
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||||
#endif /* CONFIG_CPU_MIPSR6 */
|
|
||||||
|
|
||||||
.Lfirst_fixup\@:
|
.Lfirst_fixup\@:
|
||||||
/* unset_bytes already in a2 */
|
/* unset_bytes already in a2 */
|
||||||
jr ra
|
jr ra
|
||||||
nop
|
|
||||||
|
|
||||||
.Lfwd_fixup\@:
|
.Lfwd_fixup\@:
|
||||||
/*
|
/*
|
||||||
|
@ -255,8 +258,8 @@
|
||||||
andi a2, 0x3f
|
andi a2, 0x3f
|
||||||
LONG_L t0, THREAD_BUADDR(t0)
|
LONG_L t0, THREAD_BUADDR(t0)
|
||||||
LONG_ADDU a2, t1
|
LONG_ADDU a2, t1
|
||||||
|
LONG_SUBU a2, t0
|
||||||
jr ra
|
jr ra
|
||||||
LONG_SUBU a2, t0
|
|
||||||
|
|
||||||
.Lpartial_fixup\@:
|
.Lpartial_fixup\@:
|
||||||
/*
|
/*
|
||||||
|
@ -267,24 +270,21 @@
|
||||||
andi a2, STORMASK
|
andi a2, STORMASK
|
||||||
LONG_L t0, THREAD_BUADDR(t0)
|
LONG_L t0, THREAD_BUADDR(t0)
|
||||||
LONG_ADDU a2, a0
|
LONG_ADDU a2, a0
|
||||||
|
LONG_SUBU a2, t0
|
||||||
jr ra
|
jr ra
|
||||||
LONG_SUBU a2, t0
|
|
||||||
|
|
||||||
.Llast_fixup\@:
|
.Llast_fixup\@:
|
||||||
/* unset_bytes already in a2 */
|
/* unset_bytes already in a2 */
|
||||||
jr ra
|
jr ra
|
||||||
nop
|
|
||||||
|
|
||||||
.Lsmall_fixup\@:
|
.Lsmall_fixup\@:
|
||||||
/*
|
/*
|
||||||
* unset_bytes = end_addr - current_addr + 1
|
* unset_bytes = end_addr - current_addr + 1
|
||||||
* a2 = t1 - a0 + 1
|
* a2 = t1 - a0 + 1
|
||||||
*/
|
*/
|
||||||
.set reorder
|
|
||||||
PTR_SUBU a2, t1, a0
|
PTR_SUBU a2, t1, a0
|
||||||
PTR_ADDIU a2, 1
|
PTR_ADDIU a2, 1
|
||||||
jr ra
|
jr ra
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ -298,8 +298,8 @@
|
||||||
|
|
||||||
LEAF(memset)
|
LEAF(memset)
|
||||||
EXPORT_SYMBOL(memset)
|
EXPORT_SYMBOL(memset)
|
||||||
|
move v0, a0 /* result */
|
||||||
beqz a1, 1f
|
beqz a1, 1f
|
||||||
move v0, a0 /* result */
|
|
||||||
|
|
||||||
andi a1, 0xff /* spread fillword */
|
andi a1, 0xff /* spread fillword */
|
||||||
LONG_SLL t1, a1, 8
|
LONG_SLL t1, a1, 8
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
|
obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
|
||||||
bonito-irq.o mem.o machtype.o platform.o serial.o
|
bonito-irq.o mem.o machtype.o platform.o serial.o
|
||||||
obj-$(CONFIG_PCI) += pci.o
|
obj-$(CONFIG_PCI) += pci.o
|
||||||
obj-$(CONFIG_CPU_LOONGSON2) += dma.o
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Serial port support
|
# Serial port support
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
# Makefile for Lemote Fuloong2e mini-PC board.
|
# Makefile for Lemote Fuloong2e mini-PC board.
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y += irq.o reset.o
|
obj-y += irq.o reset.o dma.o
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <linux/dma-direct.h>
|
||||||
|
|
||||||
|
dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
|
||||||
|
{
|
||||||
|
return paddr | 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
|
||||||
|
{
|
||||||
|
return dma_addr & 0x7fffffff;
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
# Makefile for lemote loongson2f family machines
|
# Makefile for lemote loongson2f family machines
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o
|
obj-y += clock.o machtype.o irq.o reset.o dma.o ec_kb3310b.o
|
||||||
|
|
||||||
#
|
#
|
||||||
# Suspend Support
|
# Suspend Support
|
||||||
|
|
|
@ -8,11 +8,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
|
||||||
|
|
||||||
phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
|
phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
|
|
||||||
if (dma_addr > 0x8fffffff)
|
if (dma_addr > 0x8fffffff)
|
||||||
return dma_addr;
|
return dma_addr;
|
||||||
return dma_addr & 0x0fffffff;
|
return dma_addr & 0x0fffffff;
|
||||||
#else
|
|
||||||
return dma_addr & 0x7fffffff;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
|
@ -96,51 +96,8 @@ void mach_irq_dispatch(unsigned int pending)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irqaction cascade_irqaction = {
|
static inline void mask_loongson_irq(struct irq_data *d) { }
|
||||||
.handler = no_action,
|
static inline void unmask_loongson_irq(struct irq_data *d) { }
|
||||||
.flags = IRQF_NO_SUSPEND,
|
|
||||||
.name = "cascade",
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void mask_loongson_irq(struct irq_data *d)
|
|
||||||
{
|
|
||||||
clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
|
||||||
irq_disable_hazard();
|
|
||||||
|
|
||||||
/* Workaround: UART IRQ may deliver to any core */
|
|
||||||
if (d->irq == LOONGSON_UART_IRQ) {
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
|
|
||||||
int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
|
|
||||||
u64 intenclr_addr = smp_group[node_id] |
|
|
||||||
(u64)(&LOONGSON_INT_ROUTER_INTENCLR);
|
|
||||||
u64 introuter_lpc_addr = smp_group[node_id] |
|
|
||||||
(u64)(&LOONGSON_INT_ROUTER_LPC);
|
|
||||||
|
|
||||||
*(volatile u32 *)intenclr_addr = 1 << 10;
|
|
||||||
*(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void unmask_loongson_irq(struct irq_data *d)
|
|
||||||
{
|
|
||||||
/* Workaround: UART IRQ may deliver to any core */
|
|
||||||
if (d->irq == LOONGSON_UART_IRQ) {
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
|
|
||||||
int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
|
|
||||||
u64 intenset_addr = smp_group[node_id] |
|
|
||||||
(u64)(&LOONGSON_INT_ROUTER_INTENSET);
|
|
||||||
u64 introuter_lpc_addr = smp_group[node_id] |
|
|
||||||
(u64)(&LOONGSON_INT_ROUTER_LPC);
|
|
||||||
|
|
||||||
*(volatile u32 *)intenset_addr = 1 << 10;
|
|
||||||
*(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
|
||||||
irq_enable_hazard();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For MIPS IRQs which shared by all cores */
|
/* For MIPS IRQs which shared by all cores */
|
||||||
static struct irq_chip loongson_irq_chip = {
|
static struct irq_chip loongson_irq_chip = {
|
||||||
|
@ -183,12 +140,11 @@ void __init mach_init_irq(void)
|
||||||
chip->irq_set_affinity = plat_set_irq_affinity;
|
chip->irq_set_affinity = plat_set_irq_affinity;
|
||||||
|
|
||||||
irq_set_chip_and_handler(LOONGSON_UART_IRQ,
|
irq_set_chip_and_handler(LOONGSON_UART_IRQ,
|
||||||
&loongson_irq_chip, handle_level_irq);
|
&loongson_irq_chip, handle_percpu_irq);
|
||||||
|
irq_set_chip_and_handler(LOONGSON_BRIDGE_IRQ,
|
||||||
|
&loongson_irq_chip, handle_percpu_irq);
|
||||||
|
|
||||||
/* setup HT1 irq */
|
set_c0_status(STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP6);
|
||||||
setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction);
|
|
||||||
|
|
||||||
set_c0_status(STATUSF_IP2 | STATUSF_IP6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
|
|
@ -180,43 +180,39 @@ static void __init szmem(unsigned int node)
|
||||||
|
|
||||||
static void __init node_mem_init(unsigned int node)
|
static void __init node_mem_init(unsigned int node)
|
||||||
{
|
{
|
||||||
unsigned long bootmap_size;
|
|
||||||
unsigned long node_addrspace_offset;
|
unsigned long node_addrspace_offset;
|
||||||
unsigned long start_pfn, end_pfn, freepfn;
|
unsigned long start_pfn, end_pfn;
|
||||||
|
|
||||||
node_addrspace_offset = nid_to_addroffset(node);
|
node_addrspace_offset = nid_to_addroffset(node);
|
||||||
pr_info("Node%d's addrspace_offset is 0x%lx\n",
|
pr_info("Node%d's addrspace_offset is 0x%lx\n",
|
||||||
node, node_addrspace_offset);
|
node, node_addrspace_offset);
|
||||||
|
|
||||||
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
|
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
|
||||||
freepfn = start_pfn;
|
pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx\n",
|
||||||
if (node == 0)
|
node, start_pfn, end_pfn);
|
||||||
freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */
|
|
||||||
pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n",
|
|
||||||
node, start_pfn, end_pfn, freepfn);
|
|
||||||
|
|
||||||
__node_data[node] = prealloc__node_data + node;
|
__node_data[node] = prealloc__node_data + node;
|
||||||
|
|
||||||
NODE_DATA(node)->bdata = &bootmem_node_data[node];
|
|
||||||
NODE_DATA(node)->node_start_pfn = start_pfn;
|
NODE_DATA(node)->node_start_pfn = start_pfn;
|
||||||
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
||||||
|
|
||||||
bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn,
|
|
||||||
start_pfn, end_pfn);
|
|
||||||
free_bootmem_with_active_regions(node, end_pfn);
|
free_bootmem_with_active_regions(node, end_pfn);
|
||||||
if (node == 0) /* used by finalize_initrd() */
|
|
||||||
|
if (node == 0) {
|
||||||
|
/* kernel end address */
|
||||||
|
unsigned long kernel_end_pfn = PFN_UP(__pa_symbol(&_end));
|
||||||
|
|
||||||
|
/* used by finalize_initrd() */
|
||||||
max_low_pfn = end_pfn;
|
max_low_pfn = end_pfn;
|
||||||
|
|
||||||
/* This is reserved for the kernel and bdata->node_bootmem_map */
|
/* Reserve the kernel text/data/bss */
|
||||||
reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT,
|
memblock_reserve(start_pfn << PAGE_SHIFT,
|
||||||
((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size,
|
((kernel_end_pfn - start_pfn) << PAGE_SHIFT));
|
||||||
BOOTMEM_DEFAULT);
|
|
||||||
|
|
||||||
if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) {
|
|
||||||
/* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
|
/* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
|
||||||
reserve_bootmem_node(NODE_DATA(node),
|
if (node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT))
|
||||||
(node_addrspace_offset | 0xfe000000),
|
memblock_reserve((node_addrspace_offset | 0xfe000000),
|
||||||
32 << 20, BOOTMEM_DEFAULT);
|
32 << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
sparse_memory_present_with_active_regions(node);
|
sparse_memory_present_with_active_regions(node);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/sched/task_stack.h>
|
#include <linux/sched/task_stack.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/clock.h>
|
#include <asm/clock.h>
|
||||||
|
@ -349,7 +350,7 @@ static void loongson3_smp_finish(void)
|
||||||
write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
|
write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
loongson3_ipi_write64(0,
|
loongson3_ipi_write64(0,
|
||||||
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
|
ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
|
||||||
pr_info("CPU#%d finished, CP0_ST=%x\n",
|
pr_info("CPU#%d finished, CP0_ST=%x\n",
|
||||||
smp_processor_id(), read_c0_status());
|
smp_processor_id(), read_c0_status());
|
||||||
}
|
}
|
||||||
|
@ -416,13 +417,13 @@ static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
|
||||||
cpu, startargs[0], startargs[1], startargs[2]);
|
cpu, startargs[0], startargs[1], startargs[2]);
|
||||||
|
|
||||||
loongson3_ipi_write64(startargs[3],
|
loongson3_ipi_write64(startargs[3],
|
||||||
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18));
|
ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x18);
|
||||||
loongson3_ipi_write64(startargs[2],
|
loongson3_ipi_write64(startargs[2],
|
||||||
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10));
|
ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x10);
|
||||||
loongson3_ipi_write64(startargs[1],
|
loongson3_ipi_write64(startargs[1],
|
||||||
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
|
ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x8);
|
||||||
loongson3_ipi_write64(startargs[0],
|
loongson3_ipi_write64(startargs[0],
|
||||||
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
|
ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,4 +750,7 @@ const struct plat_smp_ops loongson3_smp_ops = {
|
||||||
.cpu_disable = loongson3_cpu_disable,
|
.cpu_disable = loongson3_cpu_disable,
|
||||||
.cpu_die = loongson3_cpu_die,
|
.cpu_die = loongson3_cpu_die,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
.kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <linux/kcore.h>
|
#include <linux/kcore.h>
|
||||||
#include <linux/initrd.h>
|
#include <linux/initrd.h>
|
||||||
|
|
||||||
#include <asm/asm-offsets.h>
|
|
||||||
#include <asm/bootinfo.h>
|
#include <asm/bootinfo.h>
|
||||||
#include <asm/cachectl.h>
|
#include <asm/cachectl.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
@ -521,17 +520,13 @@ unsigned long pgd_current[NR_CPUS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER
|
|
||||||
* are constants. So we use the variants from asm-offset.h until that gcc
|
|
||||||
* will officially be retired.
|
|
||||||
*
|
|
||||||
* Align swapper_pg_dir in to 64K, allows its address to be loaded
|
* Align swapper_pg_dir in to 64K, allows its address to be loaded
|
||||||
* with a single LUI instruction in the TLB handlers. If we used
|
* with a single LUI instruction in the TLB handlers. If we used
|
||||||
* __aligned(64K), its size would get rounded up to the alignment
|
* __aligned(64K), its size would get rounded up to the alignment
|
||||||
* size, and waste space. So we place it in its own section and align
|
* size, and waste space. So we place it in its own section and align
|
||||||
* it in the linker script.
|
* it in the linker script.
|
||||||
*/
|
*/
|
||||||
pgd_t swapper_pg_dir[_PTRS_PER_PGD] __section(.bss..swapper_pg_dir);
|
pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(.bss..swapper_pg_dir);
|
||||||
#ifndef __PAGETABLE_PUD_FOLDED
|
#ifndef __PAGETABLE_PUD_FOLDED
|
||||||
pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss;
|
pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -291,7 +291,7 @@ static int __init xlp_of_pic_init(struct device_node *node,
|
||||||
/* we need a hack to get the PIC's SoC chip id */
|
/* we need a hack to get the PIC's SoC chip id */
|
||||||
ret = of_address_to_resource(node, 0, &res);
|
ret = of_address_to_resource(node, 0, &res);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("PIC %s: reg property not found!\n", node->name);
|
pr_err("PIC %pOFn: reg property not found!\n", node);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,21 +304,21 @@ static int __init xlp_of_pic_init(struct device_node *node,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (socid == NLM_NR_NODES) {
|
if (socid == NLM_NR_NODES) {
|
||||||
pr_err("PIC %s: Node mapping for bus %d not found!\n",
|
pr_err("PIC %pOFn: Node mapping for bus %d not found!\n",
|
||||||
node->name, bus);
|
node, bus);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
socid = (res.start >> 18) & 0x3;
|
socid = (res.start >> 18) & 0x3;
|
||||||
if (!nlm_node_present(socid)) {
|
if (!nlm_node_present(socid)) {
|
||||||
pr_err("PIC %s: node %d does not exist!\n",
|
pr_err("PIC %pOFn: node %d does not exist!\n",
|
||||||
node->name, socid);
|
node, socid);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nlm_node_present(socid)) {
|
if (!nlm_node_present(socid)) {
|
||||||
pr_err("PIC %s: node %d does not exist!\n", node->name, socid);
|
pr_err("PIC %pOFn: node %d does not exist!\n", node, socid);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ static int __init xlp_of_pic_init(struct device_node *node,
|
||||||
nlm_irq_to_xirq(socid, PIC_IRQ_BASE), PIC_IRQ_BASE,
|
nlm_irq_to_xirq(socid, PIC_IRQ_BASE), PIC_IRQ_BASE,
|
||||||
&xlp_pic_irq_domain_ops, NULL);
|
&xlp_pic_irq_domain_ops, NULL);
|
||||||
if (xlp_pic_domain == NULL) {
|
if (xlp_pic_domain == NULL) {
|
||||||
pr_err("PIC %s: Creating legacy domain failed!\n", node->name);
|
pr_err("PIC %pOFn: Creating legacy domain failed!\n", node);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
pr_info("Node %d: IRQ domain created for PIC@%pR\n", socid, &res);
|
pr_info("Node %d: IRQ domain created for PIC@%pR\n", socid, &res);
|
||||||
|
|
|
@ -18,22 +18,36 @@ static int loongson3_pci_config_access(unsigned char access_type,
|
||||||
int where, u32 *data)
|
int where, u32 *data)
|
||||||
{
|
{
|
||||||
unsigned char busnum = bus->number;
|
unsigned char busnum = bus->number;
|
||||||
u_int64_t addr, type;
|
|
||||||
void *addrp;
|
|
||||||
int device = PCI_SLOT(devfn);
|
|
||||||
int function = PCI_FUNC(devfn);
|
int function = PCI_FUNC(devfn);
|
||||||
|
int device = PCI_SLOT(devfn);
|
||||||
int reg = where & ~3;
|
int reg = where & ~3;
|
||||||
|
void *addrp;
|
||||||
|
u64 addr;
|
||||||
|
|
||||||
addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
|
if (where < PCI_CFG_SPACE_SIZE) { /* standard config */
|
||||||
if (busnum == 0) {
|
addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
|
||||||
if (device > 31)
|
if (busnum == 0) {
|
||||||
|
if (device > 31)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE | addr);
|
||||||
|
} else {
|
||||||
|
addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr);
|
||||||
|
}
|
||||||
|
} else if (where < PCI_CFG_SPACE_EXP_SIZE) { /* extended config */
|
||||||
|
struct pci_dev *rootdev;
|
||||||
|
|
||||||
|
rootdev = pci_get_domain_bus_and_slot(0, 0, 0);
|
||||||
|
if (!rootdev)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff));
|
|
||||||
type = 0;
|
|
||||||
|
|
||||||
|
addr = pci_resource_start(rootdev, 3);
|
||||||
|
if (!addr)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
addr |= busnum << 20 | device << 15 | function << 12 | reg;
|
||||||
|
addrp = (void *)TO_UNCAC(addr);
|
||||||
} else {
|
} else {
|
||||||
addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr));
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
type = 0x10000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access_type == PCI_ACCESS_WRITE)
|
if (access_type == PCI_ACCESS_WRITE)
|
||||||
|
|
|
@ -127,8 +127,12 @@ static void pcibios_scanbus(struct pci_controller *hose)
|
||||||
if (pci_has_flag(PCI_PROBE_ONLY)) {
|
if (pci_has_flag(PCI_PROBE_ONLY)) {
|
||||||
pci_bus_claim_resources(bus);
|
pci_bus_claim_resources(bus);
|
||||||
} else {
|
} else {
|
||||||
|
struct pci_bus *child;
|
||||||
|
|
||||||
pci_bus_size_bridges(bus);
|
pci_bus_size_bridges(bus);
|
||||||
pci_bus_assign_resources(bus);
|
pci_bus_assign_resources(bus);
|
||||||
|
list_for_each_entry(child, &bus->children, node)
|
||||||
|
pcie_bus_configure_settings(child);
|
||||||
}
|
}
|
||||||
pci_bus_add_devices(bus);
|
pci_bus_add_devices(bus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,6 +246,8 @@ static int rt288x_pci_probe(struct platform_device *pdev)
|
||||||
rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
|
rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
|
||||||
(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
|
(void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
|
||||||
|
|
||||||
|
rt2880_pci_controller.of_node = pdev->dev.of_node;
|
||||||
|
|
||||||
register_pci_controller(&rt2880_pci_controller);
|
register_pci_controller(&rt2880_pci_controller);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,13 +133,13 @@ static int __init msp_usb_setup(void)
|
||||||
* "D" for device-mode. If it works for Ethernet, why not USB...
|
* "D" for device-mode. If it works for Ethernet, why not USB...
|
||||||
* -- hammtrev, 2007/03/22
|
* -- hammtrev, 2007/03/22
|
||||||
*/
|
*/
|
||||||
snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
|
snprintf(&envstr[0], sizeof(envstr), "usbmode");
|
||||||
|
|
||||||
/* set default host mode */
|
/* set default host mode */
|
||||||
val = 1;
|
val = 1;
|
||||||
|
|
||||||
/* get environment string */
|
/* get environment string */
|
||||||
strp = prom_getenv((char *)&envstr[0]);
|
strp = prom_getenv(&envstr[0]);
|
||||||
if (strp) {
|
if (strp) {
|
||||||
/* compare string */
|
/* compare string */
|
||||||
if (!strcmp(strp, "device"))
|
if (!strcmp(strp, "device"))
|
||||||
|
|
|
@ -134,7 +134,7 @@ static int __init ralink_systick_init(struct device_node *np)
|
||||||
systick.dev.min_delta_ticks = 0x3;
|
systick.dev.min_delta_ticks = 0x3;
|
||||||
systick.dev.irq = irq_of_parse_and_map(np, 0);
|
systick.dev.irq = irq_of_parse_and_map(np, 0);
|
||||||
if (!systick.dev.irq) {
|
if (!systick.dev.irq) {
|
||||||
pr_err("%s: request_irq failed", np->name);
|
pr_err("%pOFn: request_irq failed", np);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +146,8 @@ static int __init ralink_systick_init(struct device_node *np)
|
||||||
|
|
||||||
clockevents_register_device(&systick.dev);
|
clockevents_register_device(&systick.dev);
|
||||||
|
|
||||||
pr_info("%s: running - mult: %d, shift: %d\n",
|
pr_info("%pOFn: running - mult: %d, shift: %d\n",
|
||||||
np->name, systick.dev.mult, systick.dev.shift);
|
np, systick.dev.mult, systick.dev.shift);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ static int __init ill_acc_of_setup(void)
|
||||||
|
|
||||||
pdev = of_find_device_by_node(np);
|
pdev = of_find_device_by_node(np);
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
pr_err("%s: failed to lookup pdev\n", np->name);
|
pr_err("%pOFn: failed to lookup pdev\n", np);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
|
||||||
static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
|
static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
|
||||||
static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
|
static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
|
||||||
static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
|
static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
|
||||||
|
static struct rt2880_pmx_func rt3352_cs1_func[] = {
|
||||||
|
FUNC("spi_cs1", 0, 45, 1),
|
||||||
|
FUNC("wdg_cs1", 1, 45, 1),
|
||||||
|
};
|
||||||
|
|
||||||
static struct rt2880_pmx_group rt3050_pinmux_data[] = {
|
static struct rt2880_pmx_group rt3050_pinmux_data[] = {
|
||||||
GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
|
GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
|
||||||
|
@ -75,6 +79,7 @@ static struct rt2880_pmx_group rt3352_pinmux_data[] = {
|
||||||
GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
|
GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
|
||||||
GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
|
GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
|
||||||
GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
|
GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
|
||||||
|
GRP("spi_cs1", rt3352_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1),
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -464,7 +464,7 @@ void ip22_be_interrupt(int irq)
|
||||||
die_if_kernel("Oops", regs);
|
die_if_kernel("Oops", regs);
|
||||||
force_sig(SIGBUS, current);
|
force_sig(SIGBUS, current);
|
||||||
} else if (debug_be_interrupt)
|
} else if (debug_be_interrupt)
|
||||||
show_regs((struct pt_regs *)regs);
|
show_regs(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
|
static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
|
||||||
|
|
|
@ -389,7 +389,6 @@ static void __init node_mem_init(cnodeid_t node)
|
||||||
{
|
{
|
||||||
unsigned long slot_firstpfn = slot_getbasepfn(node, 0);
|
unsigned long slot_firstpfn = slot_getbasepfn(node, 0);
|
||||||
unsigned long slot_freepfn = node_getfirstfree(node);
|
unsigned long slot_freepfn = node_getfirstfree(node);
|
||||||
unsigned long bootmap_size;
|
|
||||||
unsigned long start_pfn, end_pfn;
|
unsigned long start_pfn, end_pfn;
|
||||||
|
|
||||||
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
|
get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
|
||||||
|
@ -400,7 +399,6 @@ static void __init node_mem_init(cnodeid_t node)
|
||||||
__node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
|
__node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
|
||||||
memset(__node_data[node], 0, PAGE_SIZE);
|
memset(__node_data[node], 0, PAGE_SIZE);
|
||||||
|
|
||||||
NODE_DATA(node)->bdata = &bootmem_node_data[node];
|
|
||||||
NODE_DATA(node)->node_start_pfn = start_pfn;
|
NODE_DATA(node)->node_start_pfn = start_pfn;
|
||||||
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
||||||
|
|
||||||
|
@ -409,12 +407,11 @@ static void __init node_mem_init(cnodeid_t node)
|
||||||
slot_freepfn += PFN_UP(sizeof(struct pglist_data) +
|
slot_freepfn += PFN_UP(sizeof(struct pglist_data) +
|
||||||
sizeof(struct hub_data));
|
sizeof(struct hub_data));
|
||||||
|
|
||||||
bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
|
|
||||||
start_pfn, end_pfn);
|
|
||||||
free_bootmem_with_active_regions(node, end_pfn);
|
free_bootmem_with_active_regions(node, end_pfn);
|
||||||
reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
|
|
||||||
((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size,
|
memblock_reserve(slot_firstpfn << PAGE_SHIFT,
|
||||||
BOOTMEM_DEFAULT);
|
((slot_freepfn - slot_firstpfn) << PAGE_SHIFT));
|
||||||
|
|
||||||
sparse_memory_present_with_active_regions(node);
|
sparse_memory_present_with_active_regions(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
elf-entry
|
|
@ -0,0 +1,5 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
hostprogs-y := elf-entry
|
||||||
|
PHONY += elf-entry
|
||||||
|
elf-entry: $(obj)/elf-entry
|
||||||
|
@:
|
|
@ -0,0 +1,96 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <byteswap.h>
|
||||||
|
#include <elf.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef be32toh
|
||||||
|
/* If libc provides [bl]e{32,64}toh() then we'll use them */
|
||||||
|
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
# define be32toh(x) bswap_32(x)
|
||||||
|
# define le32toh(x) (x)
|
||||||
|
# define be64toh(x) bswap_64(x)
|
||||||
|
# define le64toh(x) (x)
|
||||||
|
#elif BYTE_ORDER == BIG_ENDIAN
|
||||||
|
# define be32toh(x) (x)
|
||||||
|
# define le32toh(x) bswap_32(x)
|
||||||
|
# define be64toh(x) (x)
|
||||||
|
# define le64toh(x) bswap_64(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
static void die(const char *msg)
|
||||||
|
{
|
||||||
|
fputs(msg, stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
uint64_t entry;
|
||||||
|
size_t nread;
|
||||||
|
FILE *file;
|
||||||
|
union {
|
||||||
|
Elf32_Ehdr ehdr32;
|
||||||
|
Elf64_Ehdr ehdr64;
|
||||||
|
} hdr;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
die("Usage: elf-entry <elf-file>\n");
|
||||||
|
|
||||||
|
file = fopen(argv[1], "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("Unable to open input file");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = fread(&hdr, 1, sizeof(hdr), file);
|
||||||
|
if (nread != sizeof(hdr)) {
|
||||||
|
perror("Unable to read input file");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(hdr.ehdr32.e_ident, ELFMAG, SELFMAG))
|
||||||
|
die("Input is not an ELF\n");
|
||||||
|
|
||||||
|
switch (hdr.ehdr32.e_ident[EI_CLASS]) {
|
||||||
|
case ELFCLASS32:
|
||||||
|
switch (hdr.ehdr32.e_ident[EI_DATA]) {
|
||||||
|
case ELFDATA2LSB:
|
||||||
|
entry = le32toh(hdr.ehdr32.e_entry);
|
||||||
|
break;
|
||||||
|
case ELFDATA2MSB:
|
||||||
|
entry = be32toh(hdr.ehdr32.e_entry);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("Invalid ELF encoding\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sign extend to form a canonical address */
|
||||||
|
entry = (int64_t)(int32_t)entry;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELFCLASS64:
|
||||||
|
switch (hdr.ehdr32.e_ident[EI_DATA]) {
|
||||||
|
case ELFDATA2LSB:
|
||||||
|
entry = le64toh(hdr.ehdr64.e_entry);
|
||||||
|
break;
|
||||||
|
case ELFDATA2MSB:
|
||||||
|
entry = be64toh(hdr.ehdr64.e_entry);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("Invalid ELF encoding\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
die("Invalid ELF class\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("0x%016" PRIx64 "\n", entry);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -960,12 +960,11 @@ void __init txx9_sramc_init(struct resource *r)
|
||||||
goto exit_put;
|
goto exit_put;
|
||||||
err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
|
err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
|
||||||
if (err) {
|
if (err) {
|
||||||
device_unregister(&dev->dev);
|
|
||||||
iounmap(dev->base);
|
iounmap(dev->base);
|
||||||
kfree(dev);
|
device_unregister(&dev->dev);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
exit_put:
|
exit_put:
|
||||||
|
iounmap(dev->base);
|
||||||
put_device(&dev->dev);
|
put_device(&dev->dev);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue