diff options
Diffstat (limited to 'packages/linux/nslu2-kernel/2.6.13/70-xscale-reset.patch')
-rw-r--r-- | packages/linux/nslu2-kernel/2.6.13/70-xscale-reset.patch | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/packages/linux/nslu2-kernel/2.6.13/70-xscale-reset.patch b/packages/linux/nslu2-kernel/2.6.13/70-xscale-reset.patch new file mode 100644 index 0000000000..4e68456e20 --- /dev/null +++ b/packages/linux/nslu2-kernel/2.6.13/70-xscale-reset.patch @@ -0,0 +1,155 @@ +--- linux-2.6.11.2/arch/arm/mm/proc-xscale.S 2005-03-09 00:12:44.000000000 -0800 ++++ linux-2.6.11.2/arch/arm/mm/proc-xscale.S 2005-06-18 15:39:22.701222319 -0700 +@@ -137,23 +137,129 @@ + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * ++ * This code is ixp425 specific with respect to the reset of ++ * the 'configuration register' - to be found at address ++ * 0xC40000020 'IXP425_EXP_CNFGO' ++ * + * loc: location to jump to for soft reset + */ + .align 5 + ENTRY(cpu_xscale_reset) ++ @ always branch to 0 ++ mov r0, #0 ++ ++ @ disable both FIQ and IRQ, put us into 32 bit ++ @ SVC mode (no thumb). + mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE + msr cpsr_c, r1 @ reset CPSR +- mrc p15, 0, r1, c1, c0, 0 @ ctrl register +- bic r1, r1, #0x0086 @ ........B....CA. +- bic r1, r1, #0x3900 @ ..VIZ..S........ +- mcr p15, 0, r1, c1, c0, 0 @ ctrl register +- mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB +- bic r1, r1, #0x0001 @ ...............M +- mcr p15, 0, r1, c1, c0, 0 @ ctrl register +- @ CAUTION: MMU turned off from this point. We count on the pipeline +- @ already containing those two last instructions to survive. ++ ++ @ disable debug, clock and power registers are ++ @ unimplemented. ++ mcr p14, 0, r0, c10, c0, 0 @ disable debug ++ ++ @ disable the performance monitor ++ mcr p14, 0, r0, c0, c1, 0 @ PMNC (ctrl reg) ++ mcr p14, 0, r0, c4, c1, 0 @ INTEN (intrpt enable) ++ ++ @ wait for p14 to complete ++ mrc p14, 0, ip, c4, c1, 0 @ arbitrary read ++ mov ip, ip @ sync ++ ++ @ clear the PID register ++ mcr p15, 0, r0, c13, c0, 0 @ OR nothing with address! ++ ++ @ unlock the TLBs and the I/D cache locks ++ mcr p15, 0, r0, c10, c8, 1 @ data TLB unlocked ++ mcr p15, 0, r0, c10, c4, 1 @ instruction TLB unlocked ++ mcr p15, 0, r0, c9, c2, 1 @ unlock data cache ++ mcr p15, 0, r0, c9, c1, 1 @ unlock instruction cache ++ ++ @ zap the minidata cache to write through with write coalescing ++ @ disabled. ++ mov r1, #0x21 @ MD=b10, K=1 ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ++ mrc p15, 0, ip, c1, c0, 0 @ read of ctrl register ++ mov ip, ip @ sync ++ mcr p15, 0, r1, c1, c0, 1 @ write through, no coalesc ++ ++ @ set the control register, the MMU is enabled but everything else ++ @ is disabled at this point, r1 contains the control register flags ++ @ the process is now in little-endian mode (no matter, we aren't ++ @ going to do any <word access) ++ mov r1, #0x79 @ 00vIz0rs.b1111caM ++ orr r1, r1, #0x1000 @ I-cache enable ++ mcr p15, 0, r1, c1, c0, 0 ++ mrc p15, 0, ip, c1, c0, 0 ++ mov ip, ip @ sync to coproc ++ mov r1, #0x78 @ 00viz0rs.b1111cam ++ ++ @ and flush the I/D cache and BTB ++ mcr p15, 0, r0, c7, c7, 0 ++ ++ @ that's most of the work. The only thing which remains is to ++ @ remap the flash memory and disable the MMU. Do some setup ++ @ for this, also get ready to set the LED to red and put in ++ @ a watchdog timer. ++ ++ @ get ready to reset the configuration registers in the expansion ++ @ bus. CFGN1 disables byte swap and interrupt. ++ ldr r3, =IXP4XX_PERIPHERAL_BASE_VIRT ++ ldr r4, [r3, #IXP4XX_EXP_CFG1_OFFSET] ++ bic r4, r4, #0x13 @ -BYTE_SWAP_EN, -SW_INT? ++ str r4, [r3, #IXP4XX_EXP_CFG1_OFFSET] ++ ++ @ load the current configuration register from its ++ @ virtual address and set the MEM_MAP bit ready to map the ++ @ flash back to address 0, but don't write it yet. ++ ldr r4, [r3, #IXP4XX_EXP_CFG0_OFFSET] ++ orr r4, r4, #0x80000000 ++ ++ @ load the GPIO OUTR register address and current value, ++ @ set the low nibble to just red LED on. ++ ldr r5, =IXP4XX_GPIO_BASE_VIRT ++ ldr r6, [r5, #IXP4XX_GPIO_GPOUTR_OFFSET] ++ bic r6, r6, #0xf ++ orr r6, r6, #0xd ++ ++ @ load the watchdog timer virtual address, set the key and ++ @ the timer and start the down counter ++ ldr r7, =IXP4XX_TIMER_BASE_VIRT ++ ldr r8, =IXP4XX_WDT_KEY @ set key ++ str r8, [r7, #IXP4XX_OSWK_OFFSET] ++ mov r8, #0x1000000 @ about 0.25 seconds ++ str r8, [r7, #IXP4XX_OSWT_OFFSET] @ set timer ++ mov r8, #(IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE) ++ str r8, [r7, #IXP4XX_OSWE_OFFSET] @ enable reset ++ ++ @ invalidate the TLBs to ensure that there isn't a match for ++ @ '0' there. + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +- mov pc, r0 ++ mrc p15, 0, ip, c1, c0, 0 @ read of ctrl register ++ mov ip, ip @ sync ++ ++ @ remap the flash (after preloading instructions into the ++ @ I-cache) then turn off the MMU and branch to 0 when it is ++ @ off. It seems that RedBoot relies on the page tables being ++ @ set up on boot, so set the page table head register too. ++ mov r7, #0x4000 @ flash page table ++ ldr r8, =IXP4XX_GPIO_BASE_PHYS @ for led setting ++ bic r9, r6, #0xc @ disk1+disk2 led on ++ str r6, [r5, #IXP4XX_GPIO_GPOUTR_OFFSET] @ red led ++ b cache ++ ++ @ cached instructions These 8 instructions are valid in the cache ++ @ along with the associated TLB as soon as the first is executed. ++ @ They are used to effect the transition back into the flash ++ @ ROM code. ++ .align 5 ++cache: str r4, [r3, #IXP4XX_EXP_CFG0_OFFSET] @0 no memory! ++ mcr p15, 0, r7, c2, c0, 0 @1 set translation table base ++ mcr p15, 0, r1, c1, c0, 0 @2 no MMU! ++ mrc p15, 0, ip, c2, c0, 0 @3 arbitrary read of cp15 ++ str r9, [r8, #IXP4XX_GPIO_GPOUTR_OFFSET] @4 red+disk1+disk2 led ++ sub pc, r0, ip, LSR #32 @5 sync and branch to zero ++ nop @6 ++ nop @7 + + /* + * cpu_xscale_do_idle() +@@ -168,8 +274,10 @@ + .align 5 + + ENTRY(cpu_xscale_do_idle) +- mov r0, #1 +- mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE ++ @ NSLU2/ixp420: not implemented in the hardware, docs ++ @ say do not write! ++ @mov r0, #1 ++ @mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE + mov pc, lr + + /* ================================= CACHE ================================ */ |