Merge branches 'arnd-randcfg-fixes', 'debug', 'io' (early part), 'l2x0', 'p2v', 'pgt' (early part) and 'smp' into for-linus
This commit is contained in:
Коммит
06afb1a087
|
@ -0,0 +1,44 @@
|
|||
* ARM L2 Cache Controller
|
||||
|
||||
ARM cores often have a separate level 2 cache controller. There are various
|
||||
implementations of the L2 cache controller with compatible programming models.
|
||||
The ARM L2 cache representation in the device tree should be done as follows:
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of:
|
||||
"arm,pl310-cache"
|
||||
"arm,l220-cache"
|
||||
"arm,l210-cache"
|
||||
- cache-unified : Specifies the cache is a unified cache.
|
||||
- cache-level : Should be set to 2 for a level 2 cache.
|
||||
- reg : Physical base address and size of cache controller's memory mapped
|
||||
registers.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- arm,data-latency : Cycles of latency for Data RAM accesses. Specifies 3 cells of
|
||||
read, write and setup latencies. Minimum valid values are 1. Controllers
|
||||
without setup latency control should use a value of 0.
|
||||
- arm,tag-latency : Cycles of latency for Tag RAM accesses. Specifies 3 cells of
|
||||
read, write and setup latencies. Controllers without setup latency control
|
||||
should use 0. Controllers without separate read and write Tag RAM latency
|
||||
values should only use the first cell.
|
||||
- arm,dirty-latency : Cycles of latency for Dirty RAMs. This is a single cell.
|
||||
- arm,filter-ranges : <start length> Starting address and length of window to
|
||||
filter. Addresses in the filter window are directed to the M1 port. Other
|
||||
addresses will go to the M0 port.
|
||||
- interrupts : 1 combined interrupt.
|
||||
|
||||
Example:
|
||||
|
||||
L2: cache-controller {
|
||||
compatible = "arm,pl310-cache";
|
||||
reg = <0xfff12000 0x1000>;
|
||||
arm,data-latency = <1 1 1>;
|
||||
arm,tag-latency = <2 2 2>;
|
||||
arm,filter-latency = <0x80000000 0x8000000>;
|
||||
cache-unified;
|
||||
cache-level = <2>;
|
||||
interrupts = <45>;
|
||||
};
|
|
@ -3,7 +3,7 @@ config ARM
|
|||
default y
|
||||
select HAVE_AOUT
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select HAVE_IDE
|
||||
select HAVE_IDE if PCI || ISA || PCMCIA
|
||||
select HAVE_MEMBLOCK
|
||||
select RTC_LIB
|
||||
select SYS_SUPPORTS_APM_EMULATION
|
||||
|
@ -195,7 +195,8 @@ config VECTORS_BASE
|
|||
The base address of exception vectors.
|
||||
|
||||
config ARM_PATCH_PHYS_VIRT
|
||||
bool "Patch physical to virtual translations at runtime"
|
||||
bool "Patch physical to virtual translations at runtime" if EMBEDDED
|
||||
default y
|
||||
depends on !XIP_KERNEL && MMU
|
||||
depends on !ARCH_REALVIEW || !SPARSEMEM
|
||||
help
|
||||
|
@ -204,16 +205,12 @@ config ARM_PATCH_PHYS_VIRT
|
|||
kernel in system memory.
|
||||
|
||||
This can only be used with non-XIP MMU kernels where the base
|
||||
of physical memory is at a 16MB boundary, or theoretically 64K
|
||||
for the MSM machine class.
|
||||
of physical memory is at a 16MB boundary.
|
||||
|
||||
Only disable this option if you know that you do not require
|
||||
this feature (eg, building a kernel for a single machine) and
|
||||
you need to shrink the kernel to the minimal size.
|
||||
|
||||
config ARM_PATCH_PHYS_VIRT_16BIT
|
||||
def_bool y
|
||||
depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
|
||||
help
|
||||
This option extends the physical to virtual translation patching
|
||||
to allow physical memory down to a theoretical minimum of 64K
|
||||
boundaries.
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
|
@ -301,7 +298,6 @@ config ARCH_AT91
|
|||
select ARCH_REQUIRE_GPIOLIB
|
||||
select HAVE_CLK
|
||||
select CLKDEV_LOOKUP
|
||||
select ARM_PATCH_PHYS_VIRT if MMU
|
||||
help
|
||||
This enables support for systems based on the Atmel AT91RM9200,
|
||||
AT91SAM9 and AT91CAP9 processors.
|
||||
|
@ -385,6 +381,7 @@ config ARCH_FOOTBRIDGE
|
|||
select CPU_SA110
|
||||
select FOOTBRIDGE
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_IDE
|
||||
help
|
||||
Support for systems based on the DC21285 companion chip
|
||||
("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
|
||||
|
@ -631,6 +628,8 @@ config ARCH_PXA
|
|||
select SPARSE_IRQ
|
||||
select AUTO_ZRELADDR
|
||||
select MULTI_IRQ_HANDLER
|
||||
select ARM_CPU_SUSPEND if PM
|
||||
select HAVE_IDE
|
||||
help
|
||||
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
|
||||
|
||||
|
@ -671,6 +670,7 @@ config ARCH_RPC
|
|||
select NO_IOPORT
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
select ARCH_USES_GETTIMEOFFSET
|
||||
select HAVE_IDE
|
||||
help
|
||||
On the Acorn Risc-PC, Linux can support the internal IDE disk and
|
||||
CD-ROM interface, serial and parallel port, and the floppy drive.
|
||||
|
@ -689,6 +689,7 @@ config ARCH_SA1100
|
|||
select HAVE_SCHED_CLOCK
|
||||
select TICK_ONESHOT
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select HAVE_IDE
|
||||
help
|
||||
Support for StrongARM 11x0 based boards.
|
||||
|
||||
|
@ -1375,6 +1376,7 @@ config SMP
|
|||
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
|
||||
ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
|
||||
ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
|
||||
depends on MMU
|
||||
select USE_GENERIC_SMP_HELPERS
|
||||
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
|
||||
help
|
||||
|
@ -1407,6 +1409,31 @@ config SMP_ON_UP
|
|||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
config ARM_CPU_TOPOLOGY
|
||||
bool "Support cpu topology definition"
|
||||
depends on SMP && CPU_V7
|
||||
default y
|
||||
help
|
||||
Support ARM cpu topology definition. The MPIDR register defines
|
||||
affinity between processors which is then used to describe the cpu
|
||||
topology of an ARM System.
|
||||
|
||||
config SCHED_MC
|
||||
bool "Multi-core scheduler support"
|
||||
depends on ARM_CPU_TOPOLOGY
|
||||
help
|
||||
Multi-core scheduler support improves the CPU scheduler's decision
|
||||
making when dealing with multi-core CPU chips at a cost of slightly
|
||||
increased overhead in some places. If unsure say N here.
|
||||
|
||||
config SCHED_SMT
|
||||
bool "SMT scheduler support"
|
||||
depends on ARM_CPU_TOPOLOGY
|
||||
help
|
||||
Improves the CPU scheduler's decision making when dealing with
|
||||
MultiThreading at a cost of slightly increased overhead in some
|
||||
places. If unsure say N here.
|
||||
|
||||
config HAVE_ARM_SCU
|
||||
bool
|
||||
help
|
||||
|
@ -1482,6 +1509,7 @@ config THUMB2_KERNEL
|
|||
depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
|
||||
select AEABI
|
||||
select ARM_ASM_UNIFIED
|
||||
select ARM_UNWIND
|
||||
help
|
||||
By enabling this option, the kernel will be compiled in
|
||||
Thumb-2 mode. A compiler/assembler that understand the unified
|
||||
|
@ -2101,6 +2129,9 @@ config ARCH_SUSPEND_POSSIBLE
|
|||
CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
|
||||
def_bool y
|
||||
|
||||
config ARM_CPU_SUSPEND
|
||||
def_bool PM_SLEEP
|
||||
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
|
|
@ -65,13 +65,71 @@ config DEBUG_USER
|
|||
|
||||
# These options are only for real kernel hackers who want to get their hands dirty.
|
||||
config DEBUG_LL
|
||||
bool "Kernel low-level debugging functions"
|
||||
bool "Kernel low-level debugging functions (read help!)"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say Y here to include definitions of printascii, printch, printhex
|
||||
in the kernel. This is helpful if you are debugging code that
|
||||
executes before the console is initialized.
|
||||
|
||||
Note that selecting this option will limit the kernel to a single
|
||||
UART definition, as specified below. Attempting to boot the kernel
|
||||
image on a different platform *will not work*, so this option should
|
||||
not be enabled for kernels that are intended to be portable.
|
||||
|
||||
choice
|
||||
prompt "Kernel low-level debugging port"
|
||||
depends on DEBUG_LL
|
||||
|
||||
config DEBUG_LL_UART_NONE
|
||||
bool "No low-level debugging UART"
|
||||
help
|
||||
Say Y here if your platform doesn't provide a UART option
|
||||
below. This relies on your platform choosing the right UART
|
||||
definition internally in order for low-level debugging to
|
||||
work.
|
||||
|
||||
config DEBUG_ICEDCC
|
||||
bool "Kernel low-level debugging via EmbeddedICE DCC channel"
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct
|
||||
their output to the EmbeddedICE macrocell's DCC channel using
|
||||
co-processor 14. This is known to work on the ARM9 style ICE
|
||||
channel and on the XScale with the PEEDI.
|
||||
|
||||
Note that the system will appear to hang during boot if there
|
||||
is nothing connected to read from the DCC.
|
||||
|
||||
config DEBUG_FOOTBRIDGE_COM1
|
||||
bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
|
||||
depends on FOOTBRIDGE
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct
|
||||
their output to the 8250 at PCI COM1.
|
||||
|
||||
config DEBUG_DC21285_PORT
|
||||
bool "Kernel low-level debugging messages via footbridge serial port"
|
||||
depends on FOOTBRIDGE
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct
|
||||
their output to the serial port in the DC21285 (Footbridge).
|
||||
|
||||
config DEBUG_CLPS711X_UART1
|
||||
bool "Kernel low-level debugging messages via UART1"
|
||||
depends on ARCH_CLPS711X
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct
|
||||
their output to the first serial port on these devices.
|
||||
|
||||
config DEBUG_CLPS711X_UART2
|
||||
bool "Kernel low-level debugging messages via UART2"
|
||||
depends on ARCH_CLPS711X
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct
|
||||
their output to the second serial port on these devices.
|
||||
|
||||
endchoice
|
||||
|
||||
config EARLY_PRINTK
|
||||
bool "Early printk"
|
||||
depends on DEBUG_LL
|
||||
|
@ -80,43 +138,14 @@ config EARLY_PRINTK
|
|||
kernel low-level debugging functions. Add earlyprintk to your
|
||||
kernel parameters to enable this console.
|
||||
|
||||
config DEBUG_ICEDCC
|
||||
bool "Kernel low-level debugging via EmbeddedICE DCC channel"
|
||||
depends on DEBUG_LL
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct their
|
||||
output to the EmbeddedICE macrocell's DCC channel using
|
||||
co-processor 14. This is known to work on the ARM9 style ICE
|
||||
channel and on the XScale with the PEEDI.
|
||||
|
||||
It does include a timeout to ensure that the system does not
|
||||
totally freeze when there is nothing connected to read.
|
||||
|
||||
config OC_ETM
|
||||
bool "On-chip ETM and ETB"
|
||||
select ARM_AMBA
|
||||
depends on ARM_AMBA
|
||||
help
|
||||
Enables the on-chip embedded trace macrocell and embedded trace
|
||||
buffer driver that will allow you to collect traces of the
|
||||
kernel code.
|
||||
|
||||
config DEBUG_DC21285_PORT
|
||||
bool "Kernel low-level debugging messages via footbridge serial port"
|
||||
depends on DEBUG_LL && FOOTBRIDGE
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct their
|
||||
output to the serial port in the DC21285 (Footbridge). Saying N
|
||||
will cause the debug messages to appear on the first 16550
|
||||
serial port.
|
||||
|
||||
config DEBUG_CLPS711X_UART2
|
||||
bool "Kernel low-level debugging messages via UART2"
|
||||
depends on DEBUG_LL && ARCH_CLPS711X
|
||||
help
|
||||
Say Y here if you want the debug print routines to direct their
|
||||
output to the second serial port on these devices. Saying N will
|
||||
cause the debug messages to appear on the first serial port.
|
||||
|
||||
config DEBUG_S3C_UART
|
||||
depends on PLAT_SAMSUNG
|
||||
int "S3C UART to use for low-level debug"
|
||||
|
|
|
@ -128,6 +128,9 @@ textofs-$(CONFIG_PM_H1940) := 0x00108000
|
|||
ifeq ($(CONFIG_ARCH_SA1100),y)
|
||||
textofs-$(CONFIG_SA1111) := 0x00208000
|
||||
endif
|
||||
textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
|
||||
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
|
||||
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
|
||||
|
||||
# Machine directory name. This list is sorted alphanumerically
|
||||
# by CONFIG_* macro name.
|
||||
|
|
|
@ -180,7 +180,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
|
|||
return -EINVAL;
|
||||
|
||||
mask = 0xff << shift;
|
||||
bit = 1 << (cpu + shift);
|
||||
bit = 1 << (cpu_logical_map(cpu) + shift);
|
||||
|
||||
spin_lock(&irq_controller_lock);
|
||||
val = readl_relaxed(reg) & ~mask;
|
||||
|
@ -259,9 +259,15 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
|
|||
unsigned int irq_start)
|
||||
{
|
||||
unsigned int gic_irqs, irq_limit, i;
|
||||
u32 cpumask;
|
||||
void __iomem *base = gic->dist_base;
|
||||
u32 cpumask = 1 << smp_processor_id();
|
||||
u32 cpu = 0;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = cpu_logical_map(smp_processor_id());
|
||||
#endif
|
||||
|
||||
cpumask = 1 << cpu;
|
||||
cpumask |= cpumask << 8;
|
||||
cpumask |= cpumask << 16;
|
||||
|
||||
|
@ -382,7 +388,12 @@ void __cpuinit gic_enable_ppi(unsigned int irq)
|
|||
#ifdef CONFIG_SMP
|
||||
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
|
||||
{
|
||||
unsigned long map = *cpus_addr(*mask);
|
||||
int cpu;
|
||||
unsigned long map = 0;
|
||||
|
||||
/* Convert our logical CPU mask into a physical one. */
|
||||
for_each_cpu(cpu, mask)
|
||||
map |= 1 << cpu_logical_map(cpu);
|
||||
|
||||
/*
|
||||
* Ensure that stores to Normal memory are visible to the
|
||||
|
|
|
@ -346,7 +346,8 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
|
|||
|
||||
/* Identify which VIC cell this one is, by reading the ID */
|
||||
for (i = 0; i < 4; i++) {
|
||||
u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
|
||||
void __iomem *addr;
|
||||
addr = (void __iomem *)((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
|
||||
cellid |= (readl(addr) & 0xff) << (8 * i);
|
||||
}
|
||||
vendor = (cellid >> 12) & 0xff;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define CPUID_CACHETYPE 1
|
||||
#define CPUID_TCM 2
|
||||
#define CPUID_TLBTYPE 3
|
||||
#define CPUID_MPIDR 5
|
||||
|
||||
#define CPUID_EXT_PFR0 "c1, 0"
|
||||
#define CPUID_EXT_PFR1 "c1, 1"
|
||||
|
@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
|
|||
return read_cpuid(CPUID_TCM);
|
||||
}
|
||||
|
||||
static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
|
||||
{
|
||||
return read_cpuid(CPUID_MPIDR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intel's XScale3 core supports some v6 features (supersections, L2)
|
||||
* but advertises itself as v5 as it does not support the v6 ISA. For
|
||||
|
|
|
@ -32,7 +32,7 @@ static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
|
|||
|
||||
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
|
||||
{
|
||||
return (void *)__bus_to_virt(addr);
|
||||
return (void *)__bus_to_virt((unsigned long)addr);
|
||||
}
|
||||
|
||||
static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
|
||||
|
|
|
@ -161,7 +161,6 @@ struct expansion_card {
|
|||
|
||||
/* Private internal data */
|
||||
const char *card_desc; /* Card description */
|
||||
CONST unsigned int podaddr; /* Base Linux address for card */
|
||||
CONST loader_t loader; /* loader program */
|
||||
u64 dma_mask;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Annotations for marking C functions as exception handlers.
|
||||
*
|
||||
* These should only be used for C functions that are called from the low
|
||||
* level exception entry code and not any intervening C code.
|
||||
*/
|
||||
#ifndef __ASM_ARM_EXCEPTION_H
|
||||
#define __ASM_ARM_EXCEPTION_H
|
||||
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#define __exception __attribute__((section(".exception.text")))
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
#define __exception_irq_entry __irq_entry
|
||||
#else
|
||||
#define __exception_irq_entry __exception
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ARM_EXCEPTION_H */
|
|
@ -52,6 +52,8 @@
|
|||
#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
|
||||
#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
|
||||
#define L2X0_LOCKDOWN_STRIDE 0x08
|
||||
#define L2X0_ADDR_FILTER_START 0xC00
|
||||
#define L2X0_ADDR_FILTER_END 0xC04
|
||||
#define L2X0_TEST_OPERATION 0xF00
|
||||
#define L2X0_LINE_DATA 0xF10
|
||||
#define L2X0_LINE_TAG 0xF30
|
||||
|
@ -65,8 +67,23 @@
|
|||
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
|
||||
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
|
||||
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
|
||||
#define L2X0_CACHE_ID_RTL_MASK 0x3f
|
||||
#define L2X0_CACHE_ID_RTL_R0P0 0x0
|
||||
#define L2X0_CACHE_ID_RTL_R1P0 0x2
|
||||
#define L2X0_CACHE_ID_RTL_R2P0 0x4
|
||||
#define L2X0_CACHE_ID_RTL_R3P0 0x5
|
||||
#define L2X0_CACHE_ID_RTL_R3P1 0x6
|
||||
#define L2X0_CACHE_ID_RTL_R3P2 0x8
|
||||
|
||||
#define L2X0_AUX_CTRL_MASK 0xc0000fff
|
||||
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
|
||||
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
|
||||
#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
|
||||
#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3)
|
||||
#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
|
||||
#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6)
|
||||
#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
|
||||
#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9)
|
||||
#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
|
||||
#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
|
||||
#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
|
||||
|
@ -77,8 +94,33 @@
|
|||
#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
|
||||
#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
|
||||
|
||||
#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
|
||||
#define L2X0_LATENCY_CTRL_RD_SHIFT 4
|
||||
#define L2X0_LATENCY_CTRL_WR_SHIFT 8
|
||||
|
||||
#define L2X0_ADDR_FILTER_EN 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
|
||||
extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
|
||||
|
||||
struct l2x0_regs {
|
||||
unsigned long phy_base;
|
||||
unsigned long aux_ctrl;
|
||||
/*
|
||||
* Whether the following registers need to be saved/restored
|
||||
* depends on platform
|
||||
*/
|
||||
unsigned long tag_latency;
|
||||
unsigned long data_latency;
|
||||
unsigned long filter_start;
|
||||
unsigned long filter_end;
|
||||
unsigned long prefetch_ctrl;
|
||||
unsigned long pwr_ctrl;
|
||||
};
|
||||
|
||||
extern struct l2x0_regs l2x0_saved_regs;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,6 +109,27 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
|
|||
*/
|
||||
#include <mach/io.h>
|
||||
|
||||
/*
|
||||
* This is the limit of PC card/PCI/ISA IO space, which is by default
|
||||
* 64K if we have PC card, PCI or ISA support. Otherwise, default to
|
||||
* zero to prevent ISA/PCI drivers claiming IO space (and potentially
|
||||
* oopsing.)
|
||||
*
|
||||
* Only set this larger if you really need inb() et.al. to operate over
|
||||
* a larger address space. Note that SOC_COMMON ioremaps each sockets
|
||||
* IO space area, and so inb() et.al. must be defined to operate as per
|
||||
* readb() et.al. on such platforms.
|
||||
*/
|
||||
#ifndef IO_SPACE_LIMIT
|
||||
#if defined(CONFIG_PCMCIA_SOC_COMMON) || defined(CONFIG_PCMCIA_SOC_COMMON_MODULE)
|
||||
#define IO_SPACE_LIMIT ((resource_size_t)0xffffffff)
|
||||
#elif defined(CONFIG_PCI) || defined(CONFIG_ISA) || defined(CONFIG_PCCARD)
|
||||
#define IO_SPACE_LIMIT ((resource_size_t)0xffff)
|
||||
#else
|
||||
#define IO_SPACE_LIMIT ((resource_size_t)0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IO port access primitives
|
||||
* -------------------------
|
||||
|
@ -260,10 +281,16 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
|
|||
#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })
|
||||
#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })
|
||||
|
||||
#define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
|
||||
#define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
|
||||
|
||||
#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); })
|
||||
#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); })
|
||||
#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); })
|
||||
|
||||
#define iowrite16be(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_be16(v), p); })
|
||||
#define iowrite32be(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_be32(v), p); })
|
||||
|
||||
#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
|
||||
#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
|
||||
#define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
|
||||
|
|
|
@ -24,6 +24,10 @@ void percpu_timer_setup(void);
|
|||
*/
|
||||
asmlinkage void do_local_timer(struct pt_regs *);
|
||||
|
||||
/*
|
||||
* Called from C code
|
||||
*/
|
||||
void handle_local_timer(struct pt_regs *);
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
|
||||
|
|
|
@ -160,7 +160,6 @@
|
|||
* so that all we need to do is modify the 8-bit constant field.
|
||||
*/
|
||||
#define __PV_BITS_31_24 0x81000000
|
||||
#define __PV_BITS_23_16 0x00810000
|
||||
|
||||
extern unsigned long __pv_phys_offset;
|
||||
#define PHYS_OFFSET __pv_phys_offset
|
||||
|
@ -178,9 +177,6 @@ static inline unsigned long __virt_to_phys(unsigned long x)
|
|||
{
|
||||
unsigned long t;
|
||||
__pv_stub(x, t, "add", __PV_BITS_31_24);
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
__pv_stub(t, t, "add", __PV_BITS_23_16);
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -188,9 +184,6 @@ static inline unsigned long __phys_to_virt(unsigned long x)
|
|||
{
|
||||
unsigned long t;
|
||||
__pv_stub(x, t, "sub", __PV_BITS_31_24);
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
__pv_stub(t, t, "sub", __PV_BITS_23_16);
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -31,11 +31,7 @@ struct mod_arch_specific {
|
|||
|
||||
/* Add __virt_to_phys patching state as well */
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
|
||||
#else
|
||||
#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
|
||||
#endif
|
||||
#else
|
||||
#define MODULE_ARCH_VERMAGIC_P2V ""
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,7 @@ struct outer_cache_fns {
|
|||
void (*sync)(void);
|
||||
#endif
|
||||
void (*set_debug)(unsigned long);
|
||||
void (*resume)(void);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OUTER_CACHE
|
||||
|
@ -74,6 +75,12 @@ static inline void outer_disable(void)
|
|||
outer_cache.disable();
|
||||
}
|
||||
|
||||
static inline void outer_resume(void)
|
||||
{
|
||||
if (outer_cache.resume)
|
||||
outer_cache.resume();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
|
||||
|
|
|
@ -151,47 +151,7 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
|||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||
extern void copy_page(void *to, const void *from);
|
||||
|
||||
typedef unsigned long pteval_t;
|
||||
|
||||
#undef STRICT_MM_TYPECHECKS
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { pteval_t pte; } pte_t;
|
||||
typedef struct { unsigned long pmd; } pmd_t;
|
||||
typedef struct { unsigned long pgd[2]; } pgd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define pmd_val(x) ((x).pmd)
|
||||
#define pgd_val(x) ((x).pgd[0])
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __pmd(x) ((pmd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/*
|
||||
* .. while these make it easier on the compiler
|
||||
*/
|
||||
typedef pteval_t pte_t;
|
||||
typedef unsigned long pmd_t;
|
||||
typedef unsigned long pgd_t[2];
|
||||
typedef unsigned long pgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define pmd_val(x) (x)
|
||||
#define pgd_val(x) ((x)[0])
|
||||
#define pgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __pmd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* STRICT_MM_TYPECHECKS */
|
||||
#include <asm/pgtable-2level-types.h>
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
|
|
|
@ -105,9 +105,9 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
|
|||
}
|
||||
|
||||
static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
|
||||
unsigned long prot)
|
||||
pmdval_t prot)
|
||||
{
|
||||
unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
|
||||
pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;
|
||||
pmdp[0] = __pmd(pmdval);
|
||||
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
|
||||
flush_pmd_entry(pmdp);
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-2level-hwdef.h
|
||||
*
|
||||
* Copyright (C) 1995-2002 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_2LEVEL_HWDEF_H
|
||||
#define _ASM_PGTABLE_2LEVEL_HWDEF_H
|
||||
|
||||
/*
|
||||
* Hardware page table definitions.
|
||||
*
|
||||
* + Level 1 descriptor (PMD)
|
||||
* - common
|
||||
*/
|
||||
#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
|
||||
#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
|
||||
#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
|
||||
#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
|
||||
#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
|
||||
#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
|
||||
#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
|
||||
/*
|
||||
* - section
|
||||
*/
|
||||
#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
|
||||
#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
|
||||
#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
|
||||
#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 1) << 10)
|
||||
#define PMD_SECT_AP_READ (_AT(pmdval_t, 1) << 11)
|
||||
#define PMD_SECT_TEX(x) (_AT(pmdval_t, (x)) << 12) /* v5 */
|
||||
#define PMD_SECT_APX (_AT(pmdval_t, 1) << 15) /* v6 */
|
||||
#define PMD_SECT_S (_AT(pmdval_t, 1) << 16) /* v6 */
|
||||
#define PMD_SECT_nG (_AT(pmdval_t, 1) << 17) /* v6 */
|
||||
#define PMD_SECT_SUPER (_AT(pmdval_t, 1) << 18) /* v6 */
|
||||
#define PMD_SECT_AF (_AT(pmdval_t, 0))
|
||||
|
||||
#define PMD_SECT_UNCACHED (_AT(pmdval_t, 0))
|
||||
#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
|
||||
#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
|
||||
#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
|
||||
|
||||
/*
|
||||
* - coarse table (not used)
|
||||
*/
|
||||
|
||||
/*
|
||||
* + Level 2 descriptor (PTE)
|
||||
* - common
|
||||
*/
|
||||
#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0)
|
||||
#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
|
||||
#define PTE_TYPE_LARGE (_AT(pteval_t, 1) << 0)
|
||||
#define PTE_TYPE_SMALL (_AT(pteval_t, 2) << 0)
|
||||
#define PTE_TYPE_EXT (_AT(pteval_t, 3) << 0) /* v5 */
|
||||
#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2)
|
||||
#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3)
|
||||
|
||||
/*
|
||||
* - extended small page/tiny page
|
||||
*/
|
||||
#define PTE_EXT_XN (_AT(pteval_t, 1) << 0) /* v6 */
|
||||
#define PTE_EXT_AP_MASK (_AT(pteval_t, 3) << 4)
|
||||
#define PTE_EXT_AP0 (_AT(pteval_t, 1) << 4)
|
||||
#define PTE_EXT_AP1 (_AT(pteval_t, 2) << 4)
|
||||
#define PTE_EXT_AP_UNO_SRO (_AT(pteval_t, 0) << 4)
|
||||
#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
|
||||
#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
|
||||
#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
|
||||
#define PTE_EXT_TEX(x) (_AT(pteval_t, (x)) << 6) /* v5 */
|
||||
#define PTE_EXT_APX (_AT(pteval_t, 1) << 9) /* v6 */
|
||||
#define PTE_EXT_COHERENT (_AT(pteval_t, 1) << 9) /* XScale3 */
|
||||
#define PTE_EXT_SHARED (_AT(pteval_t, 1) << 10) /* v6 */
|
||||
#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* v6 */
|
||||
|
||||
/*
|
||||
* - small page
|
||||
*/
|
||||
#define PTE_SMALL_AP_MASK (_AT(pteval_t, 0xff) << 4)
|
||||
#define PTE_SMALL_AP_UNO_SRO (_AT(pteval_t, 0x00) << 4)
|
||||
#define PTE_SMALL_AP_UNO_SRW (_AT(pteval_t, 0x55) << 4)
|
||||
#define PTE_SMALL_AP_URO_SRW (_AT(pteval_t, 0xaa) << 4)
|
||||
#define PTE_SMALL_AP_URW_SRW (_AT(pteval_t, 0xff) << 4)
|
||||
|
||||
#define PHYS_MASK (~0UL)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-2level-types.h
|
||||
*
|
||||
* Copyright (C) 1995-2003 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_2LEVEL_TYPES_H
|
||||
#define _ASM_PGTABLE_2LEVEL_TYPES_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
typedef u32 pteval_t;
|
||||
typedef u32 pmdval_t;
|
||||
|
||||
#undef STRICT_MM_TYPECHECKS
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { pteval_t pte; } pte_t;
|
||||
typedef struct { pmdval_t pmd; } pmd_t;
|
||||
typedef struct { pmdval_t pgd[2]; } pgd_t;
|
||||
typedef struct { pteval_t pgprot; } pgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define pmd_val(x) ((x).pmd)
|
||||
#define pgd_val(x) ((x).pgd[0])
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __pmd(x) ((pmd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
#else
|
||||
/*
|
||||
* .. while these make it easier on the compiler
|
||||
*/
|
||||
typedef pteval_t pte_t;
|
||||
typedef pmdval_t pmd_t;
|
||||
typedef pmdval_t pgd_t[2];
|
||||
typedef pteval_t pgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define pmd_val(x) (x)
|
||||
#define pgd_val(x) ((x)[0])
|
||||
#define pgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __pmd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* STRICT_MM_TYPECHECKS */
|
||||
|
||||
#endif /* _ASM_PGTABLE_2LEVEL_TYPES_H */
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-2level.h
|
||||
*
|
||||
* Copyright (C) 1995-2002 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_2LEVEL_H
|
||||
#define _ASM_PGTABLE_2LEVEL_H
|
||||
|
||||
/*
|
||||
* Hardware-wise, we have a two level page table structure, where the first
|
||||
* level has 4096 entries, and the second level has 256 entries. Each entry
|
||||
* is one 32-bit word. Most of the bits in the second level entry are used
|
||||
* by hardware, and there aren't any "accessed" and "dirty" bits.
|
||||
*
|
||||
* Linux on the other hand has a three level page table structure, which can
|
||||
* be wrapped to fit a two level page table structure easily - using the PGD
|
||||
* and PTE only. However, Linux also expects one "PTE" table per page, and
|
||||
* at least a "dirty" bit.
|
||||
*
|
||||
* Therefore, we tweak the implementation slightly - we tell Linux that we
|
||||
* have 2048 entries in the first level, each of which is 8 bytes (iow, two
|
||||
* hardware pointers to the second level.) The second level contains two
|
||||
* hardware PTE tables arranged contiguously, preceded by Linux versions
|
||||
* which contain the state information Linux needs. We, therefore, end up
|
||||
* with 512 entries in the "PTE" level.
|
||||
*
|
||||
* This leads to the page tables having the following layout:
|
||||
*
|
||||
* pgd pte
|
||||
* | |
|
||||
* +--------+
|
||||
* | | +------------+ +0
|
||||
* +- - - - + | Linux pt 0 |
|
||||
* | | +------------+ +1024
|
||||
* +--------+ +0 | Linux pt 1 |
|
||||
* | |-----> +------------+ +2048
|
||||
* +- - - - + +4 | h/w pt 0 |
|
||||
* | |-----> +------------+ +3072
|
||||
* +--------+ +8 | h/w pt 1 |
|
||||
* | | +------------+ +4096
|
||||
*
|
||||
* See L_PTE_xxx below for definitions of bits in the "Linux pt", and
|
||||
* PTE_xxx for definitions of bits appearing in the "h/w pt".
|
||||
*
|
||||
* PMD_xxx definitions refer to bits in the first level page table.
|
||||
*
|
||||
* The "dirty" bit is emulated by only granting hardware write permission
|
||||
* iff the page is marked "writable" and "dirty" in the Linux PTE. This
|
||||
* means that a write to a clean page will cause a permission fault, and
|
||||
* the Linux MM layer will mark the page dirty via handle_pte_fault().
|
||||
* For the hardware to notice the permission change, the TLB entry must
|
||||
* be flushed, and ptep_set_access_flags() does that for us.
|
||||
*
|
||||
* The "accessed" or "young" bit is emulated by a similar method; we only
|
||||
* allow accesses to the page if the "young" bit is set. Accesses to the
|
||||
* page will cause a fault, and handle_pte_fault() will set the young bit
|
||||
* for us as long as the page is marked present in the corresponding Linux
|
||||
* PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is
|
||||
* up to date.
|
||||
*
|
||||
* However, when the "young" bit is cleared, we deny access to the page
|
||||
* by clearing the hardware PTE. Currently Linux does not flush the TLB
|
||||
* for us in this case, which means the TLB will retain the transation
|
||||
* until either the TLB entry is evicted under pressure, or a context
|
||||
* switch which changes the user space mapping occurs.
|
||||
*/
|
||||
#define PTRS_PER_PTE 512
|
||||
#define PTRS_PER_PMD 1
|
||||
#define PTRS_PER_PGD 2048
|
||||
|
||||
#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
|
||||
#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
|
||||
#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
|
||||
|
||||
/*
|
||||
* PMD_SHIFT determines the size of the area a second-level page table can map
|
||||
* PGDIR_SHIFT determines what a third-level page table entry can map
|
||||
*/
|
||||
#define PMD_SHIFT 21
|
||||
#define PGDIR_SHIFT 21
|
||||
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
/*
|
||||
* section address mask and size definitions.
|
||||
*/
|
||||
#define SECTION_SHIFT 20
|
||||
#define SECTION_SIZE (1UL << SECTION_SHIFT)
|
||||
#define SECTION_MASK (~(SECTION_SIZE-1))
|
||||
|
||||
/*
|
||||
* ARMv6 supersection address mask and size definitions.
|
||||
*/
|
||||
#define SUPERSECTION_SHIFT 24
|
||||
#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
|
||||
#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
|
||||
|
||||
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
|
||||
|
||||
/*
|
||||
* "Linux" PTE definitions.
|
||||
*
|
||||
* We keep two sets of PTEs - the hardware and the linux version.
|
||||
* This allows greater flexibility in the way we map the Linux bits
|
||||
* onto the hardware tables, and allows us to have YOUNG and DIRTY
|
||||
* bits.
|
||||
*
|
||||
* The PTE table pointer refers to the hardware entries; the "Linux"
|
||||
* entries are stored 1024 bytes below.
|
||||
*/
|
||||
#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
|
||||
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
|
||||
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
|
||||
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
|
||||
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
|
||||
#define L_PTE_USER (_AT(pteval_t, 1) << 8)
|
||||
#define L_PTE_XN (_AT(pteval_t, 1) << 9)
|
||||
#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
|
||||
|
||||
/*
|
||||
* These are the memory types, defined to be compatible with
|
||||
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
|
||||
*/
|
||||
#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
|
||||
#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
|
||||
#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
|
||||
#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
|
||||
#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
|
||||
#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
|
||||
#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
|
||||
#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
|
||||
#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
|
||||
#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
|
||||
#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
|
||||
|
||||
#endif /* _ASM_PGTABLE_2LEVEL_H */
|
|
@ -10,81 +10,6 @@
|
|||
#ifndef _ASMARM_PGTABLE_HWDEF_H
|
||||
#define _ASMARM_PGTABLE_HWDEF_H
|
||||
|
||||
/*
|
||||
* Hardware page table definitions.
|
||||
*
|
||||
* + Level 1 descriptor (PMD)
|
||||
* - common
|
||||
*/
|
||||
#define PMD_TYPE_MASK (3 << 0)
|
||||
#define PMD_TYPE_FAULT (0 << 0)
|
||||
#define PMD_TYPE_TABLE (1 << 0)
|
||||
#define PMD_TYPE_SECT (2 << 0)
|
||||
#define PMD_BIT4 (1 << 4)
|
||||
#define PMD_DOMAIN(x) ((x) << 5)
|
||||
#define PMD_PROTECTION (1 << 9) /* v5 */
|
||||
/*
|
||||
* - section
|
||||
*/
|
||||
#define PMD_SECT_BUFFERABLE (1 << 2)
|
||||
#define PMD_SECT_CACHEABLE (1 << 3)
|
||||
#define PMD_SECT_XN (1 << 4) /* v6 */
|
||||
#define PMD_SECT_AP_WRITE (1 << 10)
|
||||
#define PMD_SECT_AP_READ (1 << 11)
|
||||
#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
|
||||
#define PMD_SECT_APX (1 << 15) /* v6 */
|
||||
#define PMD_SECT_S (1 << 16) /* v6 */
|
||||
#define PMD_SECT_nG (1 << 17) /* v6 */
|
||||
#define PMD_SECT_SUPER (1 << 18) /* v6 */
|
||||
|
||||
#define PMD_SECT_UNCACHED (0)
|
||||
#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
|
||||
#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
|
||||
#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
|
||||
#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
|
||||
|
||||
/*
|
||||
* - coarse table (not used)
|
||||
*/
|
||||
|
||||
/*
|
||||
* + Level 2 descriptor (PTE)
|
||||
* - common
|
||||
*/
|
||||
#define PTE_TYPE_MASK (3 << 0)
|
||||
#define PTE_TYPE_FAULT (0 << 0)
|
||||
#define PTE_TYPE_LARGE (1 << 0)
|
||||
#define PTE_TYPE_SMALL (2 << 0)
|
||||
#define PTE_TYPE_EXT (3 << 0) /* v5 */
|
||||
#define PTE_BUFFERABLE (1 << 2)
|
||||
#define PTE_CACHEABLE (1 << 3)
|
||||
|
||||
/*
|
||||
* - extended small page/tiny page
|
||||
*/
|
||||
#define PTE_EXT_XN (1 << 0) /* v6 */
|
||||
#define PTE_EXT_AP_MASK (3 << 4)
|
||||
#define PTE_EXT_AP0 (1 << 4)
|
||||
#define PTE_EXT_AP1 (2 << 4)
|
||||
#define PTE_EXT_AP_UNO_SRO (0 << 4)
|
||||
#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
|
||||
#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
|
||||
#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
|
||||
#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
|
||||
#define PTE_EXT_APX (1 << 9) /* v6 */
|
||||
#define PTE_EXT_COHERENT (1 << 9) /* XScale3 */
|
||||
#define PTE_EXT_SHARED (1 << 10) /* v6 */
|
||||
#define PTE_EXT_NG (1 << 11) /* v6 */
|
||||
|
||||
/*
|
||||
* - small page
|
||||
*/
|
||||
#define PTE_SMALL_AP_MASK (0xff << 4)
|
||||
#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
|
||||
#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
|
||||
#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
|
||||
#define PTE_SMALL_AP_URW_SRW (0xff << 4)
|
||||
#include <asm/pgtable-2level-hwdef.h>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <mach/vmalloc.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
|
||||
#include <asm/pgtable-2level.h>
|
||||
|
||||
/*
|
||||
* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||
* current 8MB value just means that there will be a 8MB "hole" after the
|
||||
|
@ -41,79 +43,6 @@
|
|||
#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hardware-wise, we have a two level page table structure, where the first
|
||||
* level has 4096 entries, and the second level has 256 entries. Each entry
|
||||
* is one 32-bit word. Most of the bits in the second level entry are used
|
||||
* by hardware, and there aren't any "accessed" and "dirty" bits.
|
||||
*
|
||||
* Linux on the other hand has a three level page table structure, which can
|
||||
* be wrapped to fit a two level page table structure easily - using the PGD
|
||||
* and PTE only. However, Linux also expects one "PTE" table per page, and
|
||||
* at least a "dirty" bit.
|
||||
*
|
||||
* Therefore, we tweak the implementation slightly - we tell Linux that we
|
||||
* have 2048 entries in the first level, each of which is 8 bytes (iow, two
|
||||
* hardware pointers to the second level.) The second level contains two
|
||||
* hardware PTE tables arranged contiguously, preceded by Linux versions
|
||||
* which contain the state information Linux needs. We, therefore, end up
|
||||
* with 512 entries in the "PTE" level.
|
||||
*
|
||||
* This leads to the page tables having the following layout:
|
||||
*
|
||||
* pgd pte
|
||||
* | |
|
||||
* +--------+
|
||||
* | | +------------+ +0
|
||||
* +- - - - + | Linux pt 0 |
|
||||
* | | +------------+ +1024
|
||||
* +--------+ +0 | Linux pt 1 |
|
||||
* | |-----> +------------+ +2048
|
||||
* +- - - - + +4 | h/w pt 0 |
|
||||
* | |-----> +------------+ +3072
|
||||
* +--------+ +8 | h/w pt 1 |
|
||||
* | | +------------+ +4096
|
||||
*
|
||||
* See L_PTE_xxx below for definitions of bits in the "Linux pt", and
|
||||
* PTE_xxx for definitions of bits appearing in the "h/w pt".
|
||||
*
|
||||
* PMD_xxx definitions refer to bits in the first level page table.
|
||||
*
|
||||
* The "dirty" bit is emulated by only granting hardware write permission
|
||||
* iff the page is marked "writable" and "dirty" in the Linux PTE. This
|
||||
* means that a write to a clean page will cause a permission fault, and
|
||||
* the Linux MM layer will mark the page dirty via handle_pte_fault().
|
||||
* For the hardware to notice the permission change, the TLB entry must
|
||||
* be flushed, and ptep_set_access_flags() does that for us.
|
||||
*
|
||||
* The "accessed" or "young" bit is emulated by a similar method; we only
|
||||
* allow accesses to the page if the "young" bit is set. Accesses to the
|
||||
* page will cause a fault, and handle_pte_fault() will set the young bit
|
||||
* for us as long as the page is marked present in the corresponding Linux
|
||||
* PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is
|
||||
* up to date.
|
||||
*
|
||||
* However, when the "young" bit is cleared, we deny access to the page
|
||||
* by clearing the hardware PTE. Currently Linux does not flush the TLB
|
||||
* for us in this case, which means the TLB will retain the transation
|
||||
* until either the TLB entry is evicted under pressure, or a context
|
||||
* switch which changes the user space mapping occurs.
|
||||
*/
|
||||
#define PTRS_PER_PTE 512
|
||||
#define PTRS_PER_PMD 1
|
||||
#define PTRS_PER_PGD 2048
|
||||
|
||||
#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
|
||||
#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
|
||||
#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
|
||||
|
||||
/*
|
||||
* PMD_SHIFT determines the size of the area a second-level page table can map
|
||||
* PGDIR_SHIFT determines what a third-level page table entry can map
|
||||
*/
|
||||
#define PMD_SHIFT 21
|
||||
#define PGDIR_SHIFT 21
|
||||
|
||||
#define LIBRARY_TEXT_START 0x0c000000
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
@ -124,12 +53,6 @@ extern void __pgd_error(const char *file, int line, pgd_t);
|
|||
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
|
||||
#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
|
||||
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
/*
|
||||
* This is the lowest virtual address we can permit any user space
|
||||
|
@ -138,60 +61,6 @@ extern void __pgd_error(const char *file, int line, pgd_t);
|
|||
*/
|
||||
#define FIRST_USER_ADDRESS PAGE_SIZE
|
||||
|
||||
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
|
||||
|
||||
/*
|
||||
* section address mask and size definitions.
|
||||
*/
|
||||
#define SECTION_SHIFT 20
|
||||
#define SECTION_SIZE (1UL << SECTION_SHIFT)
|
||||
#define SECTION_MASK (~(SECTION_SIZE-1))
|
||||
|
||||
/*
|
||||
* ARMv6 supersection address mask and size definitions.
|
||||
*/
|
||||
#define SUPERSECTION_SHIFT 24
|
||||
#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
|
||||
#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
|
||||
|
||||
/*
|
||||
* "Linux" PTE definitions.
|
||||
*
|
||||
* We keep two sets of PTEs - the hardware and the linux version.
|
||||
* This allows greater flexibility in the way we map the Linux bits
|
||||
* onto the hardware tables, and allows us to have YOUNG and DIRTY
|
||||
* bits.
|
||||
*
|
||||
* The PTE table pointer refers to the hardware entries; the "Linux"
|
||||
* entries are stored 1024 bytes below.
|
||||
*/
|
||||
#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
|
||||
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
|
||||
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
|
||||
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
|
||||
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
|
||||
#define L_PTE_USER (_AT(pteval_t, 1) << 8)
|
||||
#define L_PTE_XN (_AT(pteval_t, 1) << 9)
|
||||
#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
|
||||
|
||||
/*
|
||||
* These are the memory types, defined to be compatible with
|
||||
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
|
||||
*/
|
||||
#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
|
||||
#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
|
||||
#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
|
||||
#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
|
||||
#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
|
||||
#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
|
||||
#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
|
||||
#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
|
||||
#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
|
||||
#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
|
||||
#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* The pgprot_* and protection_map entries will be fixed up in runtime
|
||||
* to include the cachable and bufferable bits based on memory policy,
|
||||
|
@ -327,10 +196,10 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
|
||||
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
return __va(pmd_val(pmd) & PAGE_MASK);
|
||||
return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
|
||||
}
|
||||
|
||||
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
|
||||
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
|
||||
|
||||
/* we don't need complex calculations here as the pmd is folded into the pgd */
|
||||
#define pmd_addr_end(addr,end) (end)
|
||||
|
@ -351,7 +220,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
|||
#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
|
||||
#define pte_unmap(pte) __pte_unmap(pte)
|
||||
|
||||
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
|
||||
#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
|
||||
#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
|
||||
|
||||
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
|
||||
|
|
|
@ -32,6 +32,11 @@ extern void show_ipi_list(struct seq_file *, int);
|
|||
*/
|
||||
asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* Called from C code, this handles an IPI.
|
||||
*/
|
||||
void handle_IPI(int ipinr, struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* Setup the set of possible CPUs (via set_cpu_possible)
|
||||
*/
|
||||
|
@ -65,6 +70,12 @@ extern void platform_secondary_init(unsigned int cpu);
|
|||
*/
|
||||
extern void platform_smp_prepare_cpus(unsigned int);
|
||||
|
||||
/*
|
||||
* Logical CPU mapping.
|
||||
*/
|
||||
extern int __cpu_logical_map[NR_CPUS];
|
||||
#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
|
||||
|
||||
/*
|
||||
* Initial data for bringing up a secondary CPU.
|
||||
*/
|
||||
|
|
|
@ -62,13 +62,6 @@
|
|||
|
||||
#include <asm/outercache.h>
|
||||
|
||||
#define __exception __attribute__((section(".exception.text")))
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
#define __exception_irq_entry __irq_entry
|
||||
#else
|
||||
#define __exception_irq_entry __exception
|
||||
#endif
|
||||
|
||||
struct thread_info;
|
||||
struct task_struct;
|
||||
|
||||
|
|
|
@ -471,7 +471,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
|
|||
* these operations. This is typically used when we are removing
|
||||
* PMD entries.
|
||||
*/
|
||||
static inline void flush_pmd_entry(pmd_t *pmd)
|
||||
static inline void flush_pmd_entry(void *pmd)
|
||||
{
|
||||
const unsigned int __tlb_flag = __cpu_tlb_flags;
|
||||
|
||||
|
@ -487,7 +487,7 @@ static inline void flush_pmd_entry(pmd_t *pmd)
|
|||
dsb();
|
||||
}
|
||||
|
||||
static inline void clean_pmd_entry(pmd_t *pmd)
|
||||
static inline void clean_pmd_entry(void *pmd)
|
||||
{
|
||||
const unsigned int __tlb_flag = __cpu_tlb_flags;
|
||||
|
||||
|
|
|
@ -1,6 +1,39 @@
|
|||
#ifndef _ASM_ARM_TOPOLOGY_H
|
||||
#define _ASM_ARM_TOPOLOGY_H
|
||||
|
||||
#ifdef CONFIG_ARM_CPU_TOPOLOGY
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
struct cputopo_arm {
|
||||
int thread_id;
|
||||
int core_id;
|
||||
int socket_id;
|
||||
cpumask_t thread_sibling;
|
||||
cpumask_t core_sibling;
|
||||
};
|
||||
|
||||
extern struct cputopo_arm cpu_topology[NR_CPUS];
|
||||
|
||||
#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
|
||||
#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
|
||||
#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
|
||||
#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
|
||||
|
||||
#define mc_capable() (cpu_topology[0].socket_id != -1)
|
||||
#define smt_capable() (cpu_topology[0].thread_id != -1)
|
||||
|
||||
void init_cpu_topology(void);
|
||||
void store_cpu_topology(unsigned int cpuid);
|
||||
const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
|
||||
|
||||
#else
|
||||
|
||||
static inline void init_cpu_topology(void) { }
|
||||
static inline void store_cpu_topology(unsigned int cpuid) { }
|
||||
|
||||
#endif
|
||||
|
||||
#include <asm-generic/topology.h>
|
||||
|
||||
#endif /* _ASM_ARM_TOPOLOGY_H */
|
||||
|
|
|
@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
|
|||
obj-$(CONFIG_ARTHUR) += arthur.o
|
||||
obj-$(CONFIG_ISA_DMA) += dma-isa.o
|
||||
obj-$(CONFIG_PCI) += bios32.o isa.o
|
||||
obj-$(CONFIG_PM_SLEEP) += sleep.o
|
||||
obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o
|
||||
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
|
||||
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
|
||||
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
|
||||
|
@ -66,6 +66,7 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
|||
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
|
||||
|
||||
ifneq ($(CONFIG_ARCH_EBSA110),y)
|
||||
obj-y += io.o
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <asm/thread_info.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/procinfo.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <linux/kbuild.h>
|
||||
|
||||
/*
|
||||
|
@ -92,6 +93,17 @@ int main(void)
|
|||
DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
|
||||
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
|
||||
BLANK();
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
DEFINE(L2X0_R_PHY_BASE, offsetof(struct l2x0_regs, phy_base));
|
||||
DEFINE(L2X0_R_AUX_CTRL, offsetof(struct l2x0_regs, aux_ctrl));
|
||||
DEFINE(L2X0_R_TAG_LATENCY, offsetof(struct l2x0_regs, tag_latency));
|
||||
DEFINE(L2X0_R_DATA_LATENCY, offsetof(struct l2x0_regs, data_latency));
|
||||
DEFINE(L2X0_R_FILTER_START, offsetof(struct l2x0_regs, filter_start));
|
||||
DEFINE(L2X0_R_FILTER_END, offsetof(struct l2x0_regs, filter_end));
|
||||
DEFINE(L2X0_R_PREFETCH_CTRL, offsetof(struct l2x0_regs, prefetch_ctrl));
|
||||
DEFINE(L2X0_R_PWR_CTRL, offsetof(struct l2x0_regs, pwr_ctrl));
|
||||
BLANK();
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_HAS_ASID
|
||||
DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
|
||||
BLANK();
|
||||
|
|
|
@ -412,6 +412,9 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
|
||||
bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
|
||||
}
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_fixup_bus);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert from Linux-centric to bus-centric addresses for bridge devices.
|
||||
|
@ -431,6 +434,7 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
|
|||
region->start = res->start - offset;
|
||||
region->end = res->end - offset;
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
|
||||
void __devinit
|
||||
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
||||
|
@ -447,12 +451,7 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
|
|||
res->start = region->start + offset;
|
||||
res->end = region->end + offset;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
EXPORT_SYMBOL(pcibios_fixup_bus);
|
||||
EXPORT_SYMBOL(pcibios_resource_to_bus);
|
||||
EXPORT_SYMBOL(pcibios_bus_to_resource);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Swizzle the device pin each time we cross a bridge.
|
||||
|
|
|
@ -237,7 +237,7 @@ static void ecard_init_pgtables(struct mm_struct *mm)
|
|||
|
||||
memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
|
||||
|
||||
src_pgd = pgd_offset(mm, EASI_BASE);
|
||||
src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
|
||||
dst_pgd = pgd_offset(mm, EASI_START);
|
||||
|
||||
memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
|
||||
|
@ -674,44 +674,37 @@ static int __init ecard_probeirqhw(void)
|
|||
#define ecard_probeirqhw() (0)
|
||||
#endif
|
||||
|
||||
#ifndef IO_EC_MEMC8_BASE
|
||||
#define IO_EC_MEMC8_BASE 0
|
||||
#endif
|
||||
|
||||
static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
|
||||
static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
|
||||
{
|
||||
unsigned long address = 0;
|
||||
void __iomem *address = NULL;
|
||||
int slot = ec->slot_no;
|
||||
|
||||
if (ec->slot_no == 8)
|
||||
return IO_EC_MEMC8_BASE;
|
||||
return ECARD_MEMC8_BASE;
|
||||
|
||||
ectcr &= ~(1 << slot);
|
||||
|
||||
switch (type) {
|
||||
case ECARD_MEMC:
|
||||
if (slot < 4)
|
||||
address = IO_EC_MEMC_BASE + (slot << 12);
|
||||
address = ECARD_MEMC_BASE + (slot << 14);
|
||||
break;
|
||||
|
||||
case ECARD_IOC:
|
||||
if (slot < 4)
|
||||
address = IO_EC_IOC_BASE + (slot << 12);
|
||||
#ifdef IO_EC_IOC4_BASE
|
||||
address = ECARD_IOC_BASE + (slot << 14);
|
||||
else
|
||||
address = IO_EC_IOC4_BASE + ((slot - 4) << 12);
|
||||
#endif
|
||||
address = ECARD_IOC4_BASE + ((slot - 4) << 14);
|
||||
if (address)
|
||||
address += speed << 17;
|
||||
address += speed << 19;
|
||||
break;
|
||||
|
||||
#ifdef IO_EC_EASI_BASE
|
||||
case ECARD_EASI:
|
||||
address = IO_EC_EASI_BASE + (slot << 22);
|
||||
address = ECARD_EASI_BASE + (slot << 24);
|
||||
if (speed == ECARD_FAST)
|
||||
ectcr |= 1 << slot;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -990,6 +983,7 @@ ecard_probe(int slot, card_type_t type)
|
|||
ecard_t **ecp;
|
||||
ecard_t *ec;
|
||||
struct ex_ecid cid;
|
||||
void __iomem *addr;
|
||||
int i, rc;
|
||||
|
||||
ec = ecard_alloc_card(type, slot);
|
||||
|
@ -999,7 +993,7 @@ ecard_probe(int slot, card_type_t type)
|
|||
}
|
||||
|
||||
rc = -ENODEV;
|
||||
if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
|
||||
if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
|
||||
goto nodev;
|
||||
|
||||
cid.r_zero = 1;
|
||||
|
@ -1019,7 +1013,7 @@ ecard_probe(int slot, card_type_t type)
|
|||
ec->cid.fiqmask = cid.r_fiqmask;
|
||||
ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
|
||||
ec->fiqaddr =
|
||||
ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr);
|
||||
ec->irqaddr = addr;
|
||||
|
||||
if (ec->cid.is) {
|
||||
ec->irqmask = ec->cid.irqmask;
|
||||
|
@ -1048,10 +1042,8 @@ ecard_probe(int slot, card_type_t type)
|
|||
set_irq_flags(ec->irq, IRQF_VALID);
|
||||
}
|
||||
|
||||
#ifdef IO_EC_MEMC8_BASE
|
||||
if (slot == 8)
|
||||
ec->irq = 11;
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_RPC
|
||||
/* On RiscPC, only first two slots have DMA capability */
|
||||
if (slot < 2)
|
||||
|
@ -1097,9 +1089,7 @@ static int __init ecard_init(void)
|
|||
ecard_probe(slot, ECARD_IOC);
|
||||
}
|
||||
|
||||
#ifdef IO_EC_MEMC8_BASE
|
||||
ecard_probe(8, ECARD_IOC);
|
||||
#endif
|
||||
|
||||
irqhw = ecard_probeirqhw();
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <asm/memory.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
#include <mach/debug-macro.S>
|
||||
|
@ -38,11 +39,14 @@
|
|||
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
|
||||
#endif
|
||||
|
||||
#define PG_DIR_SIZE 0x4000
|
||||
#define PMD_ORDER 2
|
||||
|
||||
.globl swapper_pg_dir
|
||||
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
|
||||
.equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
|
||||
|
||||
.macro pgtbl, rd, phys
|
||||
add \rd, \phys, #TEXT_OFFSET - 0x4000
|
||||
add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
|
@ -148,11 +152,11 @@ __create_page_tables:
|
|||
pgtbl r4, r8 @ page table address
|
||||
|
||||
/*
|
||||
* Clear the 16K level 1 swapper page table
|
||||
* Clear the swapper page table
|
||||
*/
|
||||
mov r0, r4
|
||||
mov r3, #0
|
||||
add r6, r0, #0x4000
|
||||
add r6, r0, #PG_DIR_SIZE
|
||||
1: str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
|
@ -171,30 +175,30 @@ __create_page_tables:
|
|||
sub r0, r0, r3 @ virt->phys offset
|
||||
add r5, r5, r0 @ phys __enable_mmu
|
||||
add r6, r6, r0 @ phys __enable_mmu_end
|
||||
mov r5, r5, lsr #20
|
||||
mov r6, r6, lsr #20
|
||||
mov r5, r5, lsr #SECTION_SHIFT
|
||||
mov r6, r6, lsr #SECTION_SHIFT
|
||||
|
||||
1: orr r3, r7, r5, lsl #20 @ flags + kernel base
|
||||
str r3, [r4, r5, lsl #2] @ identity mapping
|
||||
teq r5, r6
|
||||
addne r5, r5, #1 @ next section
|
||||
bne 1b
|
||||
1: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base
|
||||
str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping
|
||||
cmp r5, r6
|
||||
addlo r5, r5, #1 @ next section
|
||||
blo 1b
|
||||
|
||||
/*
|
||||
* Now setup the pagetables for our kernel direct
|
||||
* mapped region.
|
||||
*/
|
||||
mov r3, pc
|
||||
mov r3, r3, lsr #20
|
||||
orr r3, r7, r3, lsl #20
|
||||
add r0, r4, #(KERNEL_START & 0xff000000) >> 18
|
||||
str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
|
||||
mov r3, r3, lsr #SECTION_SHIFT
|
||||
orr r3, r7, r3, lsl #SECTION_SHIFT
|
||||
add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
|
||||
str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
|
||||
ldr r6, =(KERNEL_END - 1)
|
||||
add r0, r0, #4
|
||||
add r6, r4, r6, lsr #18
|
||||
add r0, r0, #1 << PMD_ORDER
|
||||
add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
|
||||
1: cmp r0, r6
|
||||
add r3, r3, #1 << 20
|
||||
strls r3, [r0], #4
|
||||
add r3, r3, #1 << SECTION_SHIFT
|
||||
strls r3, [r0], #1 << PMD_ORDER
|
||||
bls 1b
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
|
@ -203,11 +207,11 @@ __create_page_tables:
|
|||
*/
|
||||
add r3, r8, #TEXT_OFFSET
|
||||
orr r3, r3, r7
|
||||
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
|
||||
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
|
||||
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
|
||||
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]!
|
||||
ldr r6, =(_end - 1)
|
||||
add r0, r0, #4
|
||||
add r6, r4, r6, lsr #18
|
||||
add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
|
||||
1: cmp r0, r6
|
||||
add r3, r3, #1 << 20
|
||||
strls r3, [r0], #4
|
||||
|
@ -218,12 +222,12 @@ __create_page_tables:
|
|||
* Then map boot params address in r2 or
|
||||
* the first 1MB of ram if boot params address is not specified.
|
||||
*/
|
||||
mov r0, r2, lsr #20
|
||||
movs r0, r0, lsl #20
|
||||
mov r0, r2, lsr #SECTION_SHIFT
|
||||
movs r0, r0, lsl #SECTION_SHIFT
|
||||
moveq r0, r8
|
||||
sub r3, r0, r8
|
||||
add r3, r3, #PAGE_OFFSET
|
||||
add r3, r4, r3, lsr #18
|
||||
add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
|
||||
orr r6, r7, r0
|
||||
str r6, [r3]
|
||||
|
||||
|
@ -236,21 +240,21 @@ __create_page_tables:
|
|||
*/
|
||||
addruart r7, r3
|
||||
|
||||
mov r3, r3, lsr #20
|
||||
mov r3, r3, lsl #2
|
||||
mov r3, r3, lsr #SECTION_SHIFT
|
||||
mov r3, r3, lsl #PMD_ORDER
|
||||
|
||||
add r0, r4, r3
|
||||
rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
|
||||
cmp r3, #0x0800 @ limit to 512MB
|
||||
movhi r3, #0x0800
|
||||
add r6, r0, r3
|
||||
mov r3, r7, lsr #20
|
||||
mov r3, r7, lsr #SECTION_SHIFT
|
||||
ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
|
||||
orr r3, r7, r3, lsl #20
|
||||
orr r3, r7, r3, lsl #SECTION_SHIFT
|
||||
1: str r3, [r0], #4
|
||||
add r3, r3, #1 << 20
|
||||
teq r0, r6
|
||||
bne 1b
|
||||
add r3, r3, #1 << SECTION_SHIFT
|
||||
cmp r0, r6
|
||||
blo 1b
|
||||
|
||||
#else /* CONFIG_DEBUG_ICEDCC */
|
||||
/* we don't need any serial debugging mappings for ICEDCC */
|
||||
|
@ -262,7 +266,7 @@ __create_page_tables:
|
|||
* If we're using the NetWinder or CATS, we also need to map
|
||||
* in the 16550-type serial port for the debug messages
|
||||
*/
|
||||
add r0, r4, #0xff000000 >> 18
|
||||
add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER)
|
||||
orr r3, r7, #0x7c000000
|
||||
str r3, [r0]
|
||||
#endif
|
||||
|
@ -272,10 +276,10 @@ __create_page_tables:
|
|||
* Similar reasons here - for debug. This is
|
||||
* only for Acorn RiscPC architectures.
|
||||
*/
|
||||
add r0, r4, #0x02000000 >> 18
|
||||
add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER)
|
||||
orr r3, r7, #0x02000000
|
||||
str r3, [r0]
|
||||
add r0, r4, #0xd8000000 >> 18
|
||||
add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
|
||||
str r3, [r0]
|
||||
#endif
|
||||
#endif
|
||||
|
@ -488,13 +492,8 @@ __fixup_pv_table:
|
|||
add r5, r5, r3 @ adjust table end address
|
||||
add r7, r7, r3 @ adjust __pv_phys_offset address
|
||||
str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
|
||||
#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
mov r6, r3, lsr #24 @ constant for add/sub instructions
|
||||
teq r3, r6, lsl #24 @ must be 16MiB aligned
|
||||
#else
|
||||
mov r6, r3, lsr #16 @ constant for add/sub instructions
|
||||
teq r3, r6, lsl #16 @ must be 64kiB aligned
|
||||
#endif
|
||||
THUMB( it ne @ cross section branch )
|
||||
bne __error
|
||||
str r6, [r7, #4] @ save to __pv_offset
|
||||
|
@ -510,20 +509,8 @@ ENDPROC(__fixup_pv_table)
|
|||
.text
|
||||
__fixup_a_pv_table:
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
lsls r0, r6, #24
|
||||
lsr r6, #8
|
||||
beq 1f
|
||||
clz r7, r0
|
||||
lsr r0, #24
|
||||
lsl r0, r7
|
||||
bic r0, 0x0080
|
||||
lsrs r7, #1
|
||||
orrcs r0, #0x0080
|
||||
orr r0, r0, r7, lsl #12
|
||||
#endif
|
||||
1: lsls r6, #24
|
||||
beq 4f
|
||||
lsls r6, #24
|
||||
beq 2f
|
||||
clz r7, r6
|
||||
lsr r6, #24
|
||||
lsl r6, r7
|
||||
|
@ -532,43 +519,25 @@ __fixup_a_pv_table:
|
|||
orrcs r6, #0x0080
|
||||
orr r6, r6, r7, lsl #12
|
||||
orr r6, #0x4000
|
||||
b 4f
|
||||
2: @ at this point the C flag is always clear
|
||||
add r7, r3
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
ldrh ip, [r7]
|
||||
tst ip, 0x0400 @ the i bit tells us LS or MS byte
|
||||
beq 3f
|
||||
cmp r0, #0 @ set C flag, and ...
|
||||
biceq ip, 0x0400 @ immediate zero value has a special encoding
|
||||
streqh ip, [r7] @ that requires the i bit cleared
|
||||
#endif
|
||||
3: ldrh ip, [r7, #2]
|
||||
b 2f
|
||||
1: add r7, r3
|
||||
ldrh ip, [r7, #2]
|
||||
and ip, 0x8f00
|
||||
orrcc ip, r6 @ mask in offset bits 31-24
|
||||
orrcs ip, r0 @ mask in offset bits 23-16
|
||||
orr ip, r6 @ mask in offset bits 31-24
|
||||
strh ip, [r7, #2]
|
||||
4: cmp r4, r5
|
||||
2: cmp r4, r5
|
||||
ldrcc r7, [r4], #4 @ use branch for delay slot
|
||||
bcc 2b
|
||||
bcc 1b
|
||||
bx lr
|
||||
#else
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
|
||||
and r0, r6, #255 @ offset bits 23-16
|
||||
mov r6, r6, lsr #8 @ offset bits 31-24
|
||||
#else
|
||||
mov r0, #0 @ just in case...
|
||||
#endif
|
||||
b 3f
|
||||
2: ldr ip, [r7, r3]
|
||||
b 2f
|
||||
1: ldr ip, [r7, r3]
|
||||
bic ip, ip, #0x000000ff
|
||||
tst ip, #0x400 @ rotate shift tells us LS or MS byte
|
||||
orrne ip, ip, r6 @ mask in offset bits 31-24
|
||||
orreq ip, ip, r0 @ mask in offset bits 23-16
|
||||
orr ip, ip, r6 @ mask in offset bits 31-24
|
||||
str ip, [r7, r3]
|
||||
3: cmp r4, r5
|
||||
2: cmp r4, r5
|
||||
ldrcc r7, [r4], #4 @ use branch for delay slot
|
||||
bcc 2b
|
||||
bcc 1b
|
||||
mov pc, lr
|
||||
#endif
|
||||
ENDPROC(__fixup_a_pv_table)
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/exception.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
|
||||
*/
|
||||
#undef MODULES_VADDR
|
||||
#define MODULES_VADDR (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK)
|
||||
#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <linux/cache.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/cpu.h>
|
||||
|
@ -31,6 +30,8 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/topology.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include <asm/tlbflush.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
/*
|
||||
* as from 2.5, kernels no longer have an init_tasks structure
|
||||
|
@ -259,6 +261,20 @@ void __ref cpu_die(void)
|
|||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
int __cpu_logical_map[NR_CPUS];
|
||||
|
||||
void __init smp_setup_processor_id(void)
|
||||
{
|
||||
int i;
|
||||
u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
|
||||
|
||||
cpu_logical_map(0) = cpu;
|
||||
for (i = 1; i < NR_CPUS; ++i)
|
||||
cpu_logical_map(i) = i == cpu ? 0 : i;
|
||||
|
||||
printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by both boot and secondaries to move global data into
|
||||
* per-processor storage.
|
||||
|
@ -268,6 +284,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
|
|||
struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
|
||||
|
||||
cpu_info->loops_per_jiffy = loops_per_jiffy;
|
||||
|
||||
store_cpu_topology(cpuid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -358,6 +376,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
|
|||
{
|
||||
unsigned int ncores = num_possible_cpus();
|
||||
|
||||
init_cpu_topology();
|
||||
|
||||
smp_store_cpu_info(smp_processor_id());
|
||||
|
||||
/*
|
||||
|
@ -459,6 +479,11 @@ static void ipi_timer(void)
|
|||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
|
||||
{
|
||||
handle_local_timer(regs);
|
||||
}
|
||||
|
||||
void handle_local_timer(struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
int cpu = smp_processor_id();
|
||||
|
@ -566,6 +591,11 @@ static void ipi_cpu_stop(unsigned int cpu)
|
|||
* Main handler for inter-processor interrupts
|
||||
*/
|
||||
asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
|
||||
{
|
||||
handle_IPI(ipinr, regs);
|
||||
}
|
||||
|
||||
void handle_IPI(int ipinr, struct pt_regs *regs)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
|
|
@ -34,7 +34,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)
|
|||
/*
|
||||
* Enable the SCU
|
||||
*/
|
||||
void __init scu_enable(void __iomem *scu_base)
|
||||
void scu_enable(void __iomem *scu_base)
|
||||
{
|
||||
u32 scu_ctrl;
|
||||
|
||||
|
|
|
@ -39,13 +39,11 @@
|
|||
*/
|
||||
static struct sys_timer *system_timer;
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
|
||||
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
|
||||
defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE)
|
||||
/* this needs a better home */
|
||||
DEFINE_SPINLOCK(rtc_lock);
|
||||
|
||||
#ifdef CONFIG_RTC_DRV_CMOS_MODULE
|
||||
EXPORT_SYMBOL(rtc_lock);
|
||||
#endif
|
||||
#endif /* pc-style 'CMOS' RTC support */
|
||||
|
||||
/* change this if you have some constant time drift */
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* arch/arm/kernel/topology.c
|
||||
*
|
||||
* Copyright (C) 2011 Linaro Limited.
|
||||
* Written by: Vincent Guittot
|
||||
*
|
||||
* based on arch/sh/kernel/topology.c
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/topology.h>
|
||||
|
||||
#define MPIDR_SMP_BITMASK (0x3 << 30)
|
||||
#define MPIDR_SMP_VALUE (0x2 << 30)
|
||||
|
||||
#define MPIDR_MT_BITMASK (0x1 << 24)
|
||||
|
||||
/*
|
||||
* These masks reflect the current use of the affinity levels.
|
||||
* The affinity level can be up to 16 bits according to ARM ARM
|
||||
*/
|
||||
|
||||
#define MPIDR_LEVEL0_MASK 0x3
|
||||
#define MPIDR_LEVEL0_SHIFT 0
|
||||
|
||||
#define MPIDR_LEVEL1_MASK 0xF
|
||||
#define MPIDR_LEVEL1_SHIFT 8
|
||||
|
||||
#define MPIDR_LEVEL2_MASK 0xFF
|
||||
#define MPIDR_LEVEL2_SHIFT 16
|
||||
|
||||
struct cputopo_arm cpu_topology[NR_CPUS];
|
||||
|
||||
const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
|
||||
{
|
||||
return &cpu_topology[cpu].core_sibling;
|
||||
}
|
||||
|
||||
/*
|
||||
* store_cpu_topology is called at boot when only one cpu is running
|
||||
* and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
|
||||
* which prevents simultaneous write access to cpu_topology array
|
||||
*/
|
||||
void store_cpu_topology(unsigned int cpuid)
|
||||
{
|
||||
struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
|
||||
unsigned int mpidr;
|
||||
unsigned int cpu;
|
||||
|
||||
/* If the cpu topology has been already set, just return */
|
||||
if (cpuid_topo->core_id != -1)
|
||||
return;
|
||||
|
||||
mpidr = read_cpuid_mpidr();
|
||||
|
||||
/* create cpu topology mapping */
|
||||
if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
|
||||
/*
|
||||
* This is a multiprocessor system
|
||||
* multiprocessor format & multiprocessor mode field are set
|
||||
*/
|
||||
|
||||
if (mpidr & MPIDR_MT_BITMASK) {
|
||||
/* core performance interdependency */
|
||||
cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
|
||||
& MPIDR_LEVEL0_MASK;
|
||||
cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
|
||||
& MPIDR_LEVEL1_MASK;
|
||||
cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
|
||||
& MPIDR_LEVEL2_MASK;
|
||||
} else {
|
||||
/* largely independent cores */
|
||||
cpuid_topo->thread_id = -1;
|
||||
cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
|
||||
& MPIDR_LEVEL0_MASK;
|
||||
cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
|
||||
& MPIDR_LEVEL1_MASK;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is an uniprocessor system
|
||||
* we are in multiprocessor format but uniprocessor system
|
||||
* or in the old uniprocessor format
|
||||
*/
|
||||
cpuid_topo->thread_id = -1;
|
||||
cpuid_topo->core_id = 0;
|
||||
cpuid_topo->socket_id = -1;
|
||||
}
|
||||
|
||||
/* update core and thread sibling masks */
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
|
||||
|
||||
if (cpuid_topo->socket_id == cpu_topo->socket_id) {
|
||||
cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
|
||||
if (cpu != cpuid)
|
||||
cpumask_set_cpu(cpu,
|
||||
&cpuid_topo->core_sibling);
|
||||
|
||||
if (cpuid_topo->core_id == cpu_topo->core_id) {
|
||||
cpumask_set_cpu(cpuid,
|
||||
&cpu_topo->thread_sibling);
|
||||
if (cpu != cpuid)
|
||||
cpumask_set_cpu(cpu,
|
||||
&cpuid_topo->thread_sibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
smp_wmb();
|
||||
|
||||
printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
|
||||
cpuid, cpu_topology[cpuid].thread_id,
|
||||
cpu_topology[cpuid].core_id,
|
||||
cpu_topology[cpuid].socket_id, mpidr);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_cpu_topology is called at boot when only one cpu is running
|
||||
* which prevent simultaneous write access to cpu_topology array
|
||||
*/
|
||||
void init_cpu_topology(void)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
/* init core mask */
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
|
||||
|
||||
cpu_topo->thread_id = -1;
|
||||
cpu_topo->core_id = -1;
|
||||
cpu_topo->socket_id = -1;
|
||||
cpumask_clear(&cpu_topo->core_sibling);
|
||||
cpumask_clear(&cpu_topo->thread_sibling);
|
||||
}
|
||||
smp_wmb();
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/traps.h>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/hardirq.h> /* for in_atomic() */
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
u8 __inb8(unsigned int port);
|
||||
void __outb8(u8 val, unsigned int port);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ if ARCH_EXYNOS4
|
|||
config CPU_EXYNOS4210
|
||||
bool
|
||||
select S3C_PL330_DMA
|
||||
select ARM_CPU_SUSPEND if PM
|
||||
help
|
||||
Enable EXYNOS4210 CPU support
|
||||
|
||||
|
|
|
@ -193,12 +193,10 @@ void __init smp_init_cpus(void)
|
|||
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
|
||||
|
||||
/* sanity check */
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_WARNING
|
||||
"EXYNOS4: no. of cores (%d) greater than configured "
|
||||
"maximum of %d - clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#define PCIO_SIZE 0x00100000
|
||||
#define PCIO_BASE MMU_IO(0xff000000, 0x7c000000)
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
/*
|
||||
* Translation of various region addresses to virtual addresses
|
||||
*/
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
/*
|
||||
* WARNING: this has to mirror definitions in platform.h
|
||||
*/
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define IO_SPACE_LIMIT 0x0000ffff
|
||||
|
||||
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
|
||||
extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/smsc911x.h>
|
||||
#include <linux/usb/msm_hsusb.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -42,6 +43,21 @@
|
|||
|
||||
extern struct sys_timer msm_timer;
|
||||
|
||||
static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag,
|
||||
char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
for (; tag->hdr.size; tag = tag_next(tag))
|
||||
if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) {
|
||||
tag->u.mem.start = 0;
|
||||
tag->u.mem.size += SZ_2M;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init msm7x30_reserve(void)
|
||||
{
|
||||
memblock_remove(0x0, SZ_2M);
|
||||
}
|
||||
|
||||
static int hsusb_phy_init_seq[] = {
|
||||
0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */
|
||||
0x02, 0x36, /* Disable CDR Auto Reset feature */
|
||||
|
@ -107,6 +123,8 @@ static void __init msm7x30_map_io(void)
|
|||
|
||||
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
|
||||
.boot_params = PLAT_PHYS_OFFSET + 0x100,
|
||||
.fixup = msm7x30_fixup,
|
||||
.reserve = msm7x30_reserve,
|
||||
.map_io = msm7x30_map_io,
|
||||
.init_irq = msm7x30_init_irq,
|
||||
.init_machine = msm7x30_init,
|
||||
|
@ -115,6 +133,8 @@ MACHINE_END
|
|||
|
||||
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
|
||||
.boot_params = PLAT_PHYS_OFFSET + 0x100,
|
||||
.fixup = msm7x30_fixup,
|
||||
.reserve = msm7x30_reserve,
|
||||
.map_io = msm7x30_map_io,
|
||||
.init_irq = msm7x30_init_irq,
|
||||
.init_machine = msm7x30_init,
|
||||
|
@ -123,6 +143,8 @@ MACHINE_END
|
|||
|
||||
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
|
||||
.boot_params = PLAT_PHYS_OFFSET + 0x100,
|
||||
.fixup = msm7x30_fixup,
|
||||
.reserve = msm7x30_reserve,
|
||||
.map_io = msm7x30_map_io,
|
||||
.init_irq = msm7x30_init_irq,
|
||||
.init_machine = msm7x30_init,
|
||||
|
|
|
@ -20,16 +20,34 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
|
||||
char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
for (; tag->hdr.size; tag = tag_next(tag))
|
||||
if (tag->hdr.tag == ATAG_MEM &&
|
||||
tag->u.mem.start == 0x40200000) {
|
||||
tag->u.mem.start = 0x40000000;
|
||||
tag->u.mem.size += SZ_2M;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init msm8960_reserve(void)
|
||||
{
|
||||
memblock_remove(0x40000000, SZ_2M);
|
||||
}
|
||||
|
||||
static void __init msm8960_map_io(void)
|
||||
{
|
||||
msm_map_msm8960_io();
|
||||
|
@ -76,6 +94,8 @@ static void __init msm8960_rumi3_init(void)
|
|||
}
|
||||
|
||||
MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
|
||||
.fixup = msm8960_fixup,
|
||||
.reserve = msm8960_reserve,
|
||||
.map_io = msm8960_map_io,
|
||||
.init_irq = msm8960_init_irq,
|
||||
.timer = &msm_timer,
|
||||
|
@ -83,6 +103,8 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
|
|||
MACHINE_END
|
||||
|
||||
MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
|
||||
.fixup = msm8960_fixup,
|
||||
.reserve = msm8960_reserve,
|
||||
.map_io = msm8960_map_io,
|
||||
.init_irq = msm8960_init_irq,
|
||||
.timer = &msm_timer,
|
||||
|
|
|
@ -20,14 +20,31 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
|
||||
static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag,
|
||||
char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
for (; tag->hdr.size; tag = tag_next(tag))
|
||||
if (tag->hdr.tag == ATAG_MEM &&
|
||||
tag->u.mem.start == 0x40200000) {
|
||||
tag->u.mem.start = 0x40000000;
|
||||
tag->u.mem.size += SZ_2M;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init msm8x60_reserve(void)
|
||||
{
|
||||
memblock_remove(0x40000000, SZ_2M);
|
||||
}
|
||||
|
||||
static void __init msm8x60_map_io(void)
|
||||
{
|
||||
|
@ -65,6 +82,8 @@ static void __init msm8x60_init(void)
|
|||
}
|
||||
|
||||
MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
|
||||
.fixup = msm8x60_fixup,
|
||||
.reserve = msm8x60_reserve,
|
||||
.map_io = msm8x60_map_io,
|
||||
.init_irq = msm8x60_init_irq,
|
||||
.init_machine = msm8x60_init,
|
||||
|
@ -72,6 +91,8 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
|
|||
MACHINE_END
|
||||
|
||||
MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
|
||||
.fixup = msm8x60_fixup,
|
||||
.reserve = msm8x60_reserve,
|
||||
.map_io = msm8x60_map_io,
|
||||
.init_irq = msm8x60_init_irq,
|
||||
.init_machine = msm8x60_init,
|
||||
|
@ -79,6 +100,8 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
|
|||
MACHINE_END
|
||||
|
||||
MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
|
||||
.fixup = msm8x60_fixup,
|
||||
.reserve = msm8x60_reserve,
|
||||
.map_io = msm8x60_map_io,
|
||||
.init_irq = msm8x60_init_irq,
|
||||
.init_machine = msm8x60_init,
|
||||
|
@ -86,6 +109,8 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
|
|||
MACHINE_END
|
||||
|
||||
MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
|
||||
.fixup = msm8x60_fixup,
|
||||
.reserve = msm8x60_reserve,
|
||||
.map_io = msm8x60_map_io,
|
||||
.init_irq = msm8x60_init_irq,
|
||||
.init_machine = msm8x60_init,
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
#elif defined(CONFIG_ARCH_QSD8X50)
|
||||
#define PLAT_PHYS_OFFSET UL(0x20000000)
|
||||
#elif defined(CONFIG_ARCH_MSM7X30)
|
||||
#define PLAT_PHYS_OFFSET UL(0x00200000)
|
||||
#define PLAT_PHYS_OFFSET UL(0x00000000)
|
||||
#elif defined(CONFIG_ARCH_MSM8X60)
|
||||
#define PLAT_PHYS_OFFSET UL(0x40200000)
|
||||
#define PLAT_PHYS_OFFSET UL(0x40000000)
|
||||
#elif defined(CONFIG_ARCH_MSM8960)
|
||||
#define PLAT_PHYS_OFFSET UL(0x40200000)
|
||||
#define PLAT_PHYS_OFFSET UL(0x40000000)
|
||||
#else
|
||||
#define PLAT_PHYS_OFFSET UL(0x10000000)
|
||||
#endif
|
||||
|
|
|
@ -156,6 +156,12 @@ void __init smp_init_cpus(void)
|
|||
{
|
||||
unsigned int i, ncores = get_core_count();
|
||||
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
set_cpu_possible(i, true);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ config ARCH_OMAP3
|
|||
select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
|
||||
select ARCH_HAS_OPP
|
||||
select PM_OPP if PM
|
||||
select ARM_CPU_SUSPEND if PM
|
||||
|
||||
config ARCH_OMAP4
|
||||
bool "TI OMAP4"
|
||||
|
@ -50,6 +51,7 @@ config ARCH_OMAP4
|
|||
select ARCH_HAS_OPP
|
||||
select PM_OPP if PM
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select ARM_CPU_SUSPEND if PM
|
||||
|
||||
comment "OMAP Core Type"
|
||||
depends on ARCH_OMAP2
|
||||
|
|
|
@ -109,12 +109,10 @@ void __init smp_init_cpus(void)
|
|||
ncores = scu_get_core_count(scu_base);
|
||||
|
||||
/* sanity check */
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_WARNING
|
||||
"OMAP4: no. of cores (%d) greater than configured "
|
||||
"maximum of %d - clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/exception.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/gpio.h>
|
||||
|
|
|
@ -52,12 +52,10 @@ void __init smp_init_cpus(void)
|
|||
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
|
||||
|
||||
/* sanity check */
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_WARNING
|
||||
"Realview: no. of cores (%d) greater than configured "
|
||||
"maximum of %d - clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#define EASI_SIZE 0x08000000 /* EASI I/O */
|
||||
#define EASI_START 0x08000000
|
||||
#define EASI_BASE 0xe5000000
|
||||
#define EASI_BASE IOMEM(0xe5000000)
|
||||
|
||||
#define IO_START 0x03000000 /* I/O */
|
||||
#define IO_SIZE 0x01000000
|
||||
|
@ -51,21 +51,20 @@
|
|||
/*
|
||||
* IO Addresses
|
||||
*/
|
||||
#define VIDC_BASE IOMEM(0xe0400000)
|
||||
#define EXPMASK_BASE 0xe0360000
|
||||
#define IOMD_BASE IOMEM(0xe0200000)
|
||||
#define IOC_BASE IOMEM(0xe0200000)
|
||||
#define PCIO_BASE IOMEM(0xe0010000)
|
||||
#define FLOPPYDMA_BASE IOMEM(0xe002a000)
|
||||
#define ECARD_EASI_BASE (EASI_BASE)
|
||||
#define VIDC_BASE (IO_BASE + 0x00400000)
|
||||
#define EXPMASK_BASE (IO_BASE + 0x00360000)
|
||||
#define ECARD_IOC4_BASE (IO_BASE + 0x00270000)
|
||||
#define ECARD_IOC_BASE (IO_BASE + 0x00240000)
|
||||
#define IOMD_BASE (IO_BASE + 0x00200000)
|
||||
#define IOC_BASE (IO_BASE + 0x00200000)
|
||||
#define ECARD_MEMC8_BASE (IO_BASE + 0x0002b000)
|
||||
#define FLOPPYDMA_BASE (IO_BASE + 0x0002a000)
|
||||
#define PCIO_BASE (IO_BASE + 0x00010000)
|
||||
#define ECARD_MEMC_BASE (IO_BASE + 0x00000000)
|
||||
|
||||
#define vidc_writel(val) __raw_writel(val, VIDC_BASE)
|
||||
|
||||
#define IO_EC_EASI_BASE 0x81400000
|
||||
#define IO_EC_IOC4_BASE 0x8009c000
|
||||
#define IO_EC_IOC_BASE 0x80090000
|
||||
#define IO_EC_MEMC8_BASE 0x8000ac00
|
||||
#define IO_EC_MEMC_BASE 0x80000000
|
||||
|
||||
#define NETSLOT_BASE 0x0302b000
|
||||
#define NETSLOT_SIZE 0x00001000
|
||||
|
||||
|
|
|
@ -15,195 +15,18 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
/*
|
||||
* We use two different types of addressing - PC style addresses, and ARM
|
||||
* addresses. PC style accesses the PC hardware with the normal PC IO
|
||||
* addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+
|
||||
* and are translated to the start of IO. Note that all addresses are
|
||||
* shifted left!
|
||||
*/
|
||||
#define __PORT_PCIO(x) (!((x) & 0x80000000))
|
||||
|
||||
/*
|
||||
* Dynamic IO functions.
|
||||
*/
|
||||
static inline void __outb (unsigned int value, unsigned int port)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__(
|
||||
"tst %2, #0x80000000\n\t"
|
||||
"mov %0, %4\n\t"
|
||||
"addeq %0, %0, %3\n\t"
|
||||
"strb %1, [%0, %2, lsl #2] @ outb"
|
||||
: "=&r" (temp)
|
||||
: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
static inline void __outw (unsigned int value, unsigned int port)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__(
|
||||
"tst %2, #0x80000000\n\t"
|
||||
"mov %0, %4\n\t"
|
||||
"addeq %0, %0, %3\n\t"
|
||||
"str %1, [%0, %2, lsl #2] @ outw"
|
||||
: "=&r" (temp)
|
||||
: "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
static inline void __outl (unsigned int value, unsigned int port)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__(
|
||||
"tst %2, #0x80000000\n\t"
|
||||
"mov %0, %4\n\t"
|
||||
"addeq %0, %0, %3\n\t"
|
||||
"str %1, [%0, %2, lsl #2] @ outl"
|
||||
: "=&r" (temp)
|
||||
: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
|
||||
static inline unsigned sz __in##fnsuffix (unsigned int port) \
|
||||
{ \
|
||||
unsigned long temp, value; \
|
||||
__asm__ __volatile__( \
|
||||
"tst %2, #0x80000000\n\t" \
|
||||
"mov %0, %4\n\t" \
|
||||
"addeq %0, %0, %3\n\t" \
|
||||
"ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \
|
||||
: "=&r" (temp), "=r" (value) \
|
||||
: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
|
||||
: "cc"); \
|
||||
return (unsigned sz)value; \
|
||||
}
|
||||
|
||||
static inline void __iomem *__deprecated __ioaddr(unsigned int port)
|
||||
{
|
||||
void __iomem *ret;
|
||||
if (__PORT_PCIO(port))
|
||||
ret = PCIO_BASE;
|
||||
else
|
||||
ret = IO_BASE;
|
||||
return ret + (port << 2);
|
||||
}
|
||||
|
||||
#define DECLARE_IO(sz,fnsuffix,instr) \
|
||||
DECLARE_DYN_IN(sz,fnsuffix,instr)
|
||||
|
||||
DECLARE_IO(char,b,"b")
|
||||
DECLARE_IO(short,w,"")
|
||||
DECLARE_IO(int,l,"")
|
||||
|
||||
#undef DECLARE_IO
|
||||
#undef DECLARE_DYN_IN
|
||||
|
||||
/*
|
||||
* Constant address IO functions
|
||||
* We need PC style IO addressing for:
|
||||
* - floppy (at 0x3f2,0x3f4,0x3f5,0x3f7)
|
||||
* - parport (at 0x278-0x27a, 0x27b-0x27f, 0x778-0x77a)
|
||||
* - 8250 serial (only for compile)
|
||||
*
|
||||
* These have to be macros for the 'J' constraint to work -
|
||||
* +/-4096 immediate operand.
|
||||
* These peripherals are found in an area of MMIO which looks very much
|
||||
* like an ISA bus, but with registers at the low byte of each word.
|
||||
*/
|
||||
#define __outbc(value,port) \
|
||||
({ \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"strb %0, [%1, %2] @ outbc" \
|
||||
: : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"strb %0, [%1, %2] @ outbc" \
|
||||
: : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
})
|
||||
|
||||
#define __inbc(port) \
|
||||
({ \
|
||||
unsigned char result; \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"ldrb %0, [%1, %2] @ inbc" \
|
||||
: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"ldrb %0, [%1, %2] @ inbc" \
|
||||
: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
result; \
|
||||
})
|
||||
|
||||
#define __outwc(value,port) \
|
||||
({ \
|
||||
unsigned long __v = value; \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"str %0, [%1, %2] @ outwc" \
|
||||
: : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"str %0, [%1, %2] @ outwc" \
|
||||
: : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
})
|
||||
|
||||
#define __inwc(port) \
|
||||
({ \
|
||||
unsigned short result; \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"ldr %0, [%1, %2] @ inwc" \
|
||||
: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"ldr %0, [%1, %2] @ inwc" \
|
||||
: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
result & 0xffff; \
|
||||
})
|
||||
|
||||
#define __outlc(value,port) \
|
||||
({ \
|
||||
unsigned long __v = value; \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"str %0, [%1, %2] @ outlc" \
|
||||
: : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"str %0, [%1, %2] @ outlc" \
|
||||
: : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
})
|
||||
|
||||
#define __inlc(port) \
|
||||
({ \
|
||||
unsigned long result; \
|
||||
if (__PORT_PCIO((port))) \
|
||||
__asm__ __volatile__( \
|
||||
"ldr %0, [%1, %2] @ inlc" \
|
||||
: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
|
||||
else \
|
||||
__asm__ __volatile__( \
|
||||
"ldr %0, [%1, %2] @ inlc" \
|
||||
: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
|
||||
result; \
|
||||
})
|
||||
|
||||
#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
|
||||
#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
|
||||
#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
|
||||
#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
|
||||
#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
|
||||
#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
|
||||
|
||||
/* the following macro is deprecated */
|
||||
#define ioaddr(port) ((unsigned long)__ioaddr((port)))
|
||||
|
||||
#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
|
||||
#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
|
||||
|
||||
#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)
|
||||
#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
|
||||
#define __io(a) (PCIO_BASE + ((a) << 2))
|
||||
|
||||
/*
|
||||
* 1:1 mapping for ioremapped regions.
|
||||
|
|
|
@ -74,7 +74,7 @@ static struct map_desc rpc_io_desc[] __initdata = {
|
|||
.length = IO_SIZE ,
|
||||
.type = MT_DEVICE
|
||||
}, { /* EASI space */
|
||||
.virtual = EASI_BASE,
|
||||
.virtual = (unsigned long)EASI_BASE,
|
||||
.pfn = __phys_to_pfn(EASI_START),
|
||||
.length = EASI_SIZE,
|
||||
.type = MT_DEVICE
|
||||
|
|
|
@ -199,8 +199,6 @@ DECLARE_IO(int,l,"")
|
|||
#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
|
||||
#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
|
||||
#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p))
|
||||
/* the following macro is deprecated */
|
||||
#define ioaddr(port) __ioaddr((port))
|
||||
|
||||
#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
|
||||
#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
/*
|
||||
* We don't actually have real ISA nor PCI buses, but there is so many
|
||||
* drivers out there that might just work if we fake them...
|
||||
* __io() is required to be an equivalent mapping to __mem_pci() for
|
||||
* SOC_COMMON to work.
|
||||
*/
|
||||
#define __io(a) __typesafe_io(a)
|
||||
#define __mem_pci(a) (a)
|
||||
|
|
|
@ -56,6 +56,12 @@ void __init smp_init_cpus(void)
|
|||
unsigned int ncores = shmobile_smp_get_core_count();
|
||||
unsigned int i;
|
||||
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
set_cpu_possible(i, true);
|
||||
|
||||
|
|
|
@ -114,10 +114,10 @@ void __init smp_init_cpus(void)
|
|||
{
|
||||
unsigned int i, ncores = scu_get_core_count(scu_base);
|
||||
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
|
|
|
@ -156,12 +156,10 @@ void __init smp_init_cpus(void)
|
|||
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
|
||||
|
||||
/* sanity check */
|
||||
if (ncores > NR_CPUS) {
|
||||
printk(KERN_WARNING
|
||||
"U8500: no. of cores (%d) greater than configured "
|
||||
"maximum of %d - clipping\n",
|
||||
ncores, NR_CPUS);
|
||||
ncores = NR_CPUS;
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; i++)
|
||||
|
|
|
@ -221,6 +221,12 @@ static void ct_ca9x4_init_cpu_map(void)
|
|||
{
|
||||
int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
|
||||
|
||||
if (ncores > nr_cpu_ids) {
|
||||
pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
|
||||
ncores, nr_cpu_ids);
|
||||
ncores = nr_cpu_ids;
|
||||
}
|
||||
|
||||
for (i = 0; i < ncores; ++i)
|
||||
set_cpu_possible(i, true);
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
#define __io(a) __typesafe_io(a)
|
||||
#define __mem_pci(a) (a)
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
#define __io(a) __typesafe_io((a) + 0xf0000000)
|
||||
#define __mem_pci(a) (a)
|
||||
|
||||
|
|
|
@ -86,16 +86,6 @@ core_param(alignment, ai_usermode, int, 0600);
|
|||
#define UM_FIXUP (1 << 1)
|
||||
#define UM_SIGNAL (1 << 2)
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static const char *usermode_action[] = {
|
||||
"ignored",
|
||||
"warn",
|
||||
"fixup",
|
||||
"fixup+warn",
|
||||
"signal",
|
||||
"signal+warn"
|
||||
};
|
||||
|
||||
/* Return true if and only if the ARMv6 unaligned access model is in use. */
|
||||
static bool cpu_is_v6_unaligned(void)
|
||||
{
|
||||
|
@ -123,6 +113,16 @@ static int safe_usermode(int new_usermode, bool warn)
|
|||
return new_usermode;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static const char *usermode_action[] = {
|
||||
"ignored",
|
||||
"warn",
|
||||
"fixup",
|
||||
"fixup+warn",
|
||||
"signal",
|
||||
"signal+warn"
|
||||
};
|
||||
|
||||
static int alignment_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "User:\t\t%lu\n", ai_user);
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
|
@ -30,11 +33,19 @@ static DEFINE_SPINLOCK(l2x0_lock);
|
|||
static uint32_t l2x0_way_mask; /* Bitmask of active ways */
|
||||
static uint32_t l2x0_size;
|
||||
|
||||
struct l2x0_regs l2x0_saved_regs;
|
||||
|
||||
struct l2x0_of_data {
|
||||
void (*setup)(const struct device_node *, __u32 *, __u32 *);
|
||||
void (*save)(void);
|
||||
void (*resume)(void);
|
||||
};
|
||||
|
||||
static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
|
||||
{
|
||||
/* wait for cache operation by line or way to complete */
|
||||
while (readl_relaxed(reg) & mask)
|
||||
;
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CACHE_PL310
|
||||
|
@ -277,7 +288,7 @@ static void l2x0_disable(void)
|
|||
spin_unlock_irqrestore(&l2x0_lock, flags);
|
||||
}
|
||||
|
||||
static void __init l2x0_unlock(__u32 cache_id)
|
||||
static void l2x0_unlock(__u32 cache_id)
|
||||
{
|
||||
int lockregs;
|
||||
int i;
|
||||
|
@ -353,6 +364,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
|||
/* l2x0 controller is disabled */
|
||||
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
|
||||
|
||||
l2x0_saved_regs.aux_ctrl = aux;
|
||||
|
||||
l2x0_inv_all();
|
||||
|
||||
/* enable L2X0 */
|
||||
|
@ -372,3 +385,202 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
|||
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
|
||||
ways, cache_id, aux, l2x0_size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static void __init l2x0_of_setup(const struct device_node *np,
|
||||
__u32 *aux_val, __u32 *aux_mask)
|
||||
{
|
||||
u32 data[2] = { 0, 0 };
|
||||
u32 tag = 0;
|
||||
u32 dirty = 0;
|
||||
u32 val = 0, mask = 0;
|
||||
|
||||
of_property_read_u32(np, "arm,tag-latency", &tag);
|
||||
if (tag) {
|
||||
mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
|
||||
val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
|
||||
}
|
||||
|
||||
of_property_read_u32_array(np, "arm,data-latency",
|
||||
data, ARRAY_SIZE(data));
|
||||
if (data[0] && data[1]) {
|
||||
mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
|
||||
L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
|
||||
val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
|
||||
((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
|
||||
}
|
||||
|
||||
of_property_read_u32(np, "arm,dirty-latency", &dirty);
|
||||
if (dirty) {
|
||||
mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
|
||||
val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
|
||||
}
|
||||
|
||||
*aux_val &= ~mask;
|
||||
*aux_val |= val;
|
||||
*aux_mask &= ~mask;
|
||||
}
|
||||
|
||||
static void __init pl310_of_setup(const struct device_node *np,
|
||||
__u32 *aux_val, __u32 *aux_mask)
|
||||
{
|
||||
u32 data[3] = { 0, 0, 0 };
|
||||
u32 tag[3] = { 0, 0, 0 };
|
||||
u32 filter[2] = { 0, 0 };
|
||||
|
||||
of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
|
||||
if (tag[0] && tag[1] && tag[2])
|
||||
writel_relaxed(
|
||||
((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
|
||||
((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
|
||||
((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
|
||||
l2x0_base + L2X0_TAG_LATENCY_CTRL);
|
||||
|
||||
of_property_read_u32_array(np, "arm,data-latency",
|
||||
data, ARRAY_SIZE(data));
|
||||
if (data[0] && data[1] && data[2])
|
||||
writel_relaxed(
|
||||
((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
|
||||
((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
|
||||
((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
|
||||
l2x0_base + L2X0_DATA_LATENCY_CTRL);
|
||||
|
||||
of_property_read_u32_array(np, "arm,filter-ranges",
|
||||
filter, ARRAY_SIZE(filter));
|
||||
if (filter[1]) {
|
||||
writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
|
||||
l2x0_base + L2X0_ADDR_FILTER_END);
|
||||
writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
|
||||
l2x0_base + L2X0_ADDR_FILTER_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init pl310_save(void)
|
||||
{
|
||||
u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
|
||||
L2X0_CACHE_ID_RTL_MASK;
|
||||
|
||||
l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
|
||||
L2X0_TAG_LATENCY_CTRL);
|
||||
l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base +
|
||||
L2X0_DATA_LATENCY_CTRL);
|
||||
l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base +
|
||||
L2X0_ADDR_FILTER_END);
|
||||
l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
|
||||
L2X0_ADDR_FILTER_START);
|
||||
|
||||
if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
|
||||
/*
|
||||
* From r2p0, there is Prefetch offset/control register
|
||||
*/
|
||||
l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base +
|
||||
L2X0_PREFETCH_CTRL);
|
||||
/*
|
||||
* From r3p0, there is Power control register
|
||||
*/
|
||||
if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
|
||||
l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
|
||||
L2X0_POWER_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
static void l2x0_resume(void)
|
||||
{
|
||||
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
||||
/* restore aux ctrl and enable l2 */
|
||||
l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
|
||||
|
||||
writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
|
||||
L2X0_AUX_CTRL);
|
||||
|
||||
l2x0_inv_all();
|
||||
|
||||
writel_relaxed(1, l2x0_base + L2X0_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
static void pl310_resume(void)
|
||||
{
|
||||
u32 l2x0_revision;
|
||||
|
||||
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
||||
/* restore pl310 setup */
|
||||
writel_relaxed(l2x0_saved_regs.tag_latency,
|
||||
l2x0_base + L2X0_TAG_LATENCY_CTRL);
|
||||
writel_relaxed(l2x0_saved_regs.data_latency,
|
||||
l2x0_base + L2X0_DATA_LATENCY_CTRL);
|
||||
writel_relaxed(l2x0_saved_regs.filter_end,
|
||||
l2x0_base + L2X0_ADDR_FILTER_END);
|
||||
writel_relaxed(l2x0_saved_regs.filter_start,
|
||||
l2x0_base + L2X0_ADDR_FILTER_START);
|
||||
|
||||
l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
|
||||
L2X0_CACHE_ID_RTL_MASK;
|
||||
|
||||
if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
|
||||
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
|
||||
l2x0_base + L2X0_PREFETCH_CTRL);
|
||||
if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
|
||||
writel_relaxed(l2x0_saved_regs.pwr_ctrl,
|
||||
l2x0_base + L2X0_POWER_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
l2x0_resume();
|
||||
}
|
||||
|
||||
static const struct l2x0_of_data pl310_data = {
|
||||
pl310_of_setup,
|
||||
pl310_save,
|
||||
pl310_resume,
|
||||
};
|
||||
|
||||
static const struct l2x0_of_data l2x0_data = {
|
||||
l2x0_of_setup,
|
||||
NULL,
|
||||
l2x0_resume,
|
||||
};
|
||||
|
||||
static const struct of_device_id l2x0_ids[] __initconst = {
|
||||
{ .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
|
||||
{ .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
|
||||
{ .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
|
||||
{}
|
||||
};
|
||||
|
||||
int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct l2x0_of_data *data;
|
||||
struct resource res;
|
||||
|
||||
np = of_find_matching_node(NULL, l2x0_ids);
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
if (of_address_to_resource(np, 0, &res))
|
||||
return -ENODEV;
|
||||
|
||||
l2x0_base = ioremap(res.start, resource_size(&res));
|
||||
if (!l2x0_base)
|
||||
return -ENOMEM;
|
||||
|
||||
l2x0_saved_regs.phy_base = res.start;
|
||||
|
||||
data = of_match_node(l2x0_ids, np)->data;
|
||||
|
||||
/* L2 configuration can only be changed if the cache is disabled */
|
||||
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
||||
if (data->setup)
|
||||
data->setup(np, &aux_val, &aux_mask);
|
||||
}
|
||||
|
||||
if (data->save)
|
||||
data->save();
|
||||
|
||||
l2x0_init(l2x0_base, aux_val, aux_mask);
|
||||
|
||||
outer_cache.resume = data->resume;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -123,8 +123,8 @@ static void __dma_free_buffer(struct page *page, size_t size)
|
|||
#endif
|
||||
|
||||
#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
|
||||
#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
|
||||
#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
|
||||
#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PMD_SHIFT)
|
||||
#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PMD_SHIFT)
|
||||
|
||||
/*
|
||||
* These are the page tables (2MB each) covering uncached, DMA consistent allocations
|
||||
|
@ -183,7 +183,7 @@ static int __init consistent_init(void)
|
|||
}
|
||||
|
||||
consistent_pte[i++] = pte;
|
||||
base += (1 << PGDIR_SHIFT);
|
||||
base += PMD_SIZE;
|
||||
} while (base < CONSISTENT_END);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/highmem.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
||||
#include <asm/exception.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
|
|
@ -12,8 +12,8 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
|
|||
|
||||
struct mem_type {
|
||||
pteval_t prot_pte;
|
||||
unsigned int prot_l1;
|
||||
unsigned int prot_sect;
|
||||
pmdval_t prot_l1;
|
||||
pmdval_t prot_sect;
|
||||
unsigned int domain;
|
||||
};
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ EXPORT_SYMBOL(pgprot_kernel);
|
|||
struct cachepolicy {
|
||||
const char policy[16];
|
||||
unsigned int cr_mask;
|
||||
unsigned int pmd;
|
||||
pmdval_t pmd;
|
||||
pteval_t pte;
|
||||
};
|
||||
|
||||
|
@ -288,7 +288,7 @@ static void __init build_mem_type_table(void)
|
|||
{
|
||||
struct cachepolicy *cp;
|
||||
unsigned int cr = get_cr();
|
||||
unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
|
||||
pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
|
||||
int cpu_arch = cpu_architecture();
|
||||
int i;
|
||||
|
||||
|
@ -863,14 +863,14 @@ static inline void prepare_page_table(void)
|
|||
/*
|
||||
* Clear out all the mappings below the kernel image.
|
||||
*/
|
||||
for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE)
|
||||
for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE)
|
||||
pmd_clear(pmd_off_k(addr));
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
/* The XIP kernel is mapped in the module area -- skip over it */
|
||||
addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
|
||||
addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
|
||||
#endif
|
||||
for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
|
||||
for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
|
||||
pmd_clear(pmd_off_k(addr));
|
||||
|
||||
/*
|
||||
|
@ -885,10 +885,12 @@ static inline void prepare_page_table(void)
|
|||
* memory bank, up to the end of the vmalloc region.
|
||||
*/
|
||||
for (addr = __phys_to_virt(end);
|
||||
addr < VMALLOC_END; addr += PGDIR_SIZE)
|
||||
addr < VMALLOC_END; addr += PMD_SIZE)
|
||||
pmd_clear(pmd_off_k(addr));
|
||||
}
|
||||
|
||||
#define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
/*
|
||||
* Reserve the special regions of memory
|
||||
*/
|
||||
|
@ -898,7 +900,7 @@ void __init arm_mm_memblock_reserve(void)
|
|||
* Reserve the page tables. These are already in use,
|
||||
* and can only be in node 0.
|
||||
*/
|
||||
memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
|
||||
memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE);
|
||||
|
||||
#ifdef CONFIG_SA1111
|
||||
/*
|
||||
|
@ -926,7 +928,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
|
|||
*/
|
||||
vectors_page = early_alloc(PAGE_SIZE);
|
||||
|
||||
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
|
||||
for (addr = VMALLOC_END; addr; addr += PMD_SIZE)
|
||||
pmd_clear(pmd_off_k(addr));
|
||||
|
||||
/*
|
||||
|
|
|
@ -218,7 +218,7 @@ ENDPROC(cpu_v7_set_pte_ext)
|
|||
/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
|
||||
.globl cpu_v7_suspend_size
|
||||
.equ cpu_v7_suspend_size, 4 * 9
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_ARM_CPU_SUSPEND
|
||||
ENTRY(cpu_v7_do_suspend)
|
||||
stmfd sp!, {r4 - r11, lr}
|
||||
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
|
||||
|
|
|
@ -14,6 +14,7 @@ config ARCH_OMAP1
|
|||
select CLKDEV_LOOKUP
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_IRQ_CHIP
|
||||
select HAVE_IDE
|
||||
help
|
||||
"Systems based on omap7xx, omap15xx or omap16xx"
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# ccflags-y := -DDEBUG
|
||||
# asflags-y := -DDEBUG
|
||||
|
||||
KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp)
|
||||
KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp -mfloat-abi=soft)
|
||||
LDFLAGS +=--no-warn-mismatch
|
||||
|
||||
obj-y += vfp.o
|
||||
|
|
|
@ -1081,7 +1081,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER
|
|||
depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
|
||||
depends on !X86_64
|
||||
select STACKTRACE
|
||||
select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE
|
||||
select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND
|
||||
help
|
||||
Provide stacktrace filter for fault-injection capabilities
|
||||
|
||||
|
@ -1091,7 +1091,7 @@ config LATENCYTOP
|
|||
depends on DEBUG_KERNEL
|
||||
depends on STACKTRACE_SUPPORT
|
||||
depends on PROC_FS
|
||||
select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE
|
||||
select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND
|
||||
select KALLSYMS
|
||||
select KALLSYMS_ALL
|
||||
select STACKTRACE
|
||||
|
|
Загрузка…
Ссылка в новой задаче