extern void read_decode_cache_bcr(void);
extern int ioc_exists;
+extern unsigned long perip_base;
#endif /* !__ASSEMBLY__ */
static void read_arc_build_cfg_regs(void)
{
- struct bcr_perip uncached_space;
struct bcr_timer timer;
struct bcr_generic bcr;
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
- unsigned long perip_space;
FIX_PTR(cpu);
READ_BCR(AUX_IDENTITY, cpu->core);
cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
- READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
- if (uncached_space.ver < 3)
- perip_space = uncached_space.start << 24;
- else
- perip_space = read_aux_reg(AUX_NON_VOL) & 0xF0000000;
-
- BUG_ON(perip_space != ARC_UNCACHED_ADDR_SPACE);
-
READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy);
cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */
FIX_PTR(cpu);
n += scnprintf(buf + n, len - n,
- "Vector Table\t: %#x\nUncached Base\t: %#x\n",
- cpu->vec_base, ARC_UNCACHED_ADDR_SPACE);
+ "Vector Table\t: %#x\nUncached Base\t: %#lx\n",
+ cpu->vec_base, perip_base);
if (cpu->extn.fpu_sp || cpu->extn.fpu_dp)
n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n",
static int l2_line_sz;
int ioc_exists;
volatile int slc_enable = 1, ioc_enable = 1;
+unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */
void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr,
unsigned long sz, const int cacheop);
static void read_decode_cache_bcr_arcv2(int cpu)
{
struct cpuinfo_arc_cache *p_slc = &cpuinfo_arc700[cpu].slc;
+ struct bcr_generic uncached_space;
struct bcr_generic sbcr;
struct bcr_slc_cfg {
READ_BCR(ARC_REG_CLUSTER_BCR, cbcr);
if (cbcr.c && ioc_enable)
ioc_exists = 1;
+
+ /* Legacy Data Uncached BCR is deprecated from v3 onwards */
+ READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
+ if (uncached_space.ver > 2)
+ perip_base = read_aux_reg(AUX_NON_VOL) & 0xF0000000;
}
void read_decode_cache_bcr(void)
#include <linux/slab.h>
#include <linux/cache.h>
+static inline bool arc_uncached_addr_space(phys_addr_t paddr)
+{
+ if (is_isa_arcompact()) {
+ if (paddr >= ARC_UNCACHED_ADDR_SPACE)
+ return true;
+ } else if (paddr >= perip_base && paddr <= 0xFFFFFFFF) {
+ return true;
+ }
+
+ return false;
+}
+
void __iomem *ioremap(phys_addr_t paddr, unsigned long size)
{
phys_addr_t end;
* If the region is h/w uncached, MMU mapping can be elided as optim
* The cast to u32 is fine as this region can only be inside 4GB
*/
- if (paddr >= ARC_UNCACHED_ADDR_SPACE)
+ if (arc_uncached_addr_space(paddr))
return (void __iomem *)(u32)paddr;
return ioremap_prot(paddr, size, PAGE_KERNEL_NO_CACHE);
void iounmap(const void __iomem *addr)
{
- if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE)
+ /* weird double cast to handle phys_addr_t > 32 bits */
+ if (arc_uncached_addr_space((phys_addr_t)(u32)addr))
return;
vfree((void *)(PAGE_MASK & (unsigned long __force)addr));