linux/arch/mips/include/asm/mach-pnx8550/kernel-entry-init.h
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2005 Embedded Alley Solutions, Inc
   7 */
   8#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
   9#define __ASM_MACH_KERNEL_ENTRY_INIT_H
  10
  11#include <asm/cacheops.h>
  12#include <asm/addrspace.h>
  13
  14#define CO_CONFIGPR_VALID  0x3F1F41FF    /* valid bits to write to ConfigPR */
  15#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
  16#define CACHE_OPC      0xBC000000  /* MIPS cache instruction opcode */
  17#define ICACHE_LINE_SIZE        32      /* Instruction cache line size bytes */
  18#define DCACHE_LINE_SIZE        32      /* Data cache line size in bytes */
  19
  20#define ICACHE_SET_COUNT        256     /* Instruction cache set count */
  21#define DCACHE_SET_COUNT        128     /* Data cache set count */
  22
  23#define ICACHE_SET_SIZE         (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
  24#define DCACHE_SET_SIZE         (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
  25
  26        .macro  kernel_entry_setup
  27        .set    push
  28        .set    noreorder
  29        /*
  30         * PNX8550 entry point, when running a non compressed
  31         * kernel. When loading a zImage, the head.S code in
  32         * arch/mips/zboot/pnx8550 will init the caches and,
  33         * decompress the kernel, and branch to kernel_entry.
  34                 */
  35cache_begin:    li      t0, (1<<28)
  36        mtc0    t0, CP0_STATUS /* cp0 usable */
  37        HAZARD_CP0
  38
  39        mtc0    zero, CP0_CAUSE
  40        HAZARD_CP0
  41
  42
  43        /* Set static virtual to phys address translation and TLB disabled */
  44        mfc0    t0, CP0_CONFIG, 7
  45        HAZARD_CP0
  46
  47        and     t0, ~((1<<19) | (1<<20))     /* TLB/MAP cleared */
  48        mtc0    t0, CP0_CONFIG, 7
  49        HAZARD_CP0
  50
  51        /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
  52
  53        init_icache
  54        nop
  55        init_dcache
  56        nop
  57
  58        cachePr4450ICReset
  59        nop
  60
  61        cachePr4450DCReset
  62        nop
  63
  64        /* read ConfigPR into t0 */
  65        mfc0    t0, CP0_CONFIG, 7
  66        HAZARD_CP0
  67
  68        /*  enable the TLB */
  69        or      t0, (1<<19)
  70
  71        /* disable the ICACHE: at least 10x slower */
  72        /* or      t0, (1<<26) */
  73
  74        /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set  */
  75        /* or      t0, (1<<27) */
  76
  77        and     t0, CO_CONFIGPR_VALID
  78
  79        /* enable TLB. */
  80        mtc0    t0, CP0_CONFIG, 7
  81        HAZARD_CP0
  82cache_end:
  83        /* Setup CMEM_0 to MMIO address space, 2MB */
  84        lui    t0, 0x1BE0
  85        addi   t0, t0, 0x3
  86        mtc0   $8, $22, 4
  87        nop
  88
  89        /* Setup CMEM_1, 128MB */
  90        lui    t0, 0x1000
  91        addi   t0, t0, 0xf
  92        mtc0   $8, $22, 5
  93        nop
  94
  95
  96        /* Setup CMEM_2, 32MB */
  97        lui    t0, 0x1C00
  98        addi   t0, t0, 0xb
  99        mtc0   $8, $22, 6
 100        nop
 101
 102        /* Setup CMEM_3, 0MB */
 103        lui    t0, 0x0
 104        addi   t0, t0, 0x0
 105        mtc0   $8, $22, 7
 106        nop
 107
 108        /* Enable cache */
 109        mfc0    t0, CP0_CONFIG
 110        HAZARD_CP0
 111        and     t0, t0, 0xFFFFFFF8
 112        or      t0, t0, 3
 113        mtc0    t0, CP0_CONFIG
 114        HAZARD_CP0
 115        .set    pop
 116        .endm
 117
 118        .macro  init_icache
 119        .set    push
 120        .set    noreorder
 121
 122        /* Get Cache Configuration */
 123        mfc0    t3, CP0_CONFIG, 1
 124        HAZARD_CP0
 125
 126        /* get cache Line size */
 127
 128        srl   t1, t3, 19   /* C0_CONFIGPR_IL_SHIFT */
 129        andi  t1, t1, 0x7  /* C0_CONFIGPR_IL_MASK */
 130        beq   t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
 131        nop
 132        addiu t0, t1, 1
 133        ori   t1, zero, 1
 134        sllv  t1, t1, t0
 135
 136        /* get max cache Index */
 137        srl   t2, t3, 22  /* C0_CONFIGPR_IS_SHIFT */
 138        andi  t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
 139        addiu t0, t2, 6
 140        ori   t2, zero, 1
 141        sllv  t2, t2, t0
 142
 143        /* get max cache way */
 144        srl   t3, t3, 16  /* C0_CONFIGPR_IA_SHIFT */
 145        andi  t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
 146        addiu t3, t3, 1
 147
 148        /* total no of cache lines */
 149        multu t2, t3             /* max index * max way */
 150        mflo  t2
 151        addiu t2, t2, -1
 152
 153        move  t0, zero
 154pr4450_next_instruction_cache_set:
 155        cache  Index_Invalidate_I, 0(t0)
 156        addu  t0, t0, t1         /* add bytes in a line */
 157        bne   t2, zero, pr4450_next_instruction_cache_set
 158        addiu t2, t2, -1   /* reduce no of lines to invalidate by one */
 159pr4450_instr_cache_invalidated:
 160        .set    pop
 161        .endm
 162
 163        .macro  init_dcache
 164        .set    push
 165        .set    noreorder
 166        move t1, zero
 167
 168        /* Store Tag Information */
 169        mtc0    zero, CP0_TAGLO, 0
 170        HAZARD_CP0
 171
 172        mtc0    zero, CP0_TAGHI, 0
 173        HAZARD_CP0
 174
 175        /* Cache size is 16384 = 512 lines x 32 bytes per line */
 176        or       t2, zero, (128*4)-1  /* 512 lines  */
 177        /* Invalidate all lines */
 1782:
 179        cache Index_Store_Tag_D, 0(t1)
 180        addiu    t2, t2, -1
 181        bne      t2, zero, 2b
 182        addiu    t1, t1, 32        /* 32 bytes in a line */
 183        .set pop
 184        .endm
 185
 186        .macro  cachePr4450ICReset
 187        .set    push
 188        .set    noreorder
 189
 190        /* Save CP0 status reg on entry; */
 191        /* disable interrupts during cache reset */
 192        mfc0    t0, CP0_STATUS      /* T0 = interrupt status on entry */
 193        HAZARD_CP0
 194
 195        mtc0    zero, CP0_STATUS   /* disable CPU interrupts */
 196        HAZARD_CP0
 197
 198        or      t1, zero, zero              /* T1 = starting cache index (0) */
 199        ori     t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
 200
 201        icache_invd_loop:
 202        /* 9 == register t1 */
 203        .word   CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
 204                (0 * ICACHE_SET_SIZE)  /* invalidate inst cache WAY0 */
 205        .word   CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
 206                (1 * ICACHE_SET_SIZE)  /* invalidate inst cache WAY1 */
 207
 208        addiu   t1, t1, ICACHE_LINE_SIZE    /* T1 = next cache line index */
 209        bne     t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
 210        addiu   t2, t2, -1        /* decrement T2 set cnt (delay slot) */
 211
 212        /* Initialize the latches in the instruction cache tag */
 213        /* that drive the way selection tri-state bus drivers, by doing a */
 214        /* dummy load while the instruction cache is still disabled. */
 215        /* TODO: Is this needed ? */
 216        la      t1, KSEG0            /* T1 = cached memory base address */
 217        lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
 218
 219        mtc0    t0, CP0_STATUS        /* restore interrupt status on entry */
 220        HAZARD_CP0
 221        .set    pop
 222        .endm
 223
 224        .macro  cachePr4450DCReset
 225        .set    push
 226        .set    noreorder
 227        mfc0    t0, CP0_STATUS           /* T0 = interrupt status on entry */
 228        HAZARD_CP0
 229        mtc0    zero, CP0_STATUS         /* disable CPU interrupts */
 230        HAZARD_CP0
 231
 232        /* Writeback/invalidate entire data cache sets/ways/lines */
 233        or      t1, zero, zero              /* T1 = starting cache index (0) */
 234        ori     t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
 235
 236        dcache_wbinvd_loop:
 237        /* 9 == register t1 */
 238        .word   CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
 239                (0 * DCACHE_SET_SIZE)  /* writeback/invalidate WAY0 */
 240        .word   CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
 241                (1 * DCACHE_SET_SIZE)  /* writeback/invalidate WAY1 */
 242        .word   CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
 243                (2 * DCACHE_SET_SIZE)  /* writeback/invalidate WAY2 */
 244        .word   CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
 245                (3 * DCACHE_SET_SIZE)  /* writeback/invalidate WAY3 */
 246
 247        addiu   t1, t1, DCACHE_LINE_SIZE  /* T1 = next data cache line index */
 248        bne     t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
 249        addiu   t2, t2, -1          /* decrement T2 set cnt (delay slot) */
 250
 251        /* Initialize the latches in the data cache tag that drive the way
 252        selection tri-state bus drivers, by doing a dummy load while the
 253        data cache is still in the disabled mode.  TODO: Is this needed ? */
 254        la      t1, KSEG0            /* T1 = cached memory base address */
 255        lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
 256
 257        mtc0    t0, CP0_STATUS       /* restore interrupt status on entry */
 258        HAZARD_CP0
 259        .set    pop
 260        .endm
 261
 262#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */
 263