libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / lzma-loader / head.S
blobac0c2f666e7a22640fbdc7ea11c54add812f8d56
1 /* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su)     */
2 /* cache manipulation adapted from Broadcom code        */
3 /* idea taken from original bunzip2 decompressor code   */
4 /* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org)  */
5 /* Licensed under the linux kernel's version of the GPL.*/
7 #include <asm/asm.h>
8 #include <asm/regdef.h>
10 #define KSEG0           0x80000000
12 #define C0_CONFIG       $16
13 #define C0_TAGLO        $28
14 #define C0_TAGHI        $29
16 #define CONF1_DA_SHIFT  7                       /* D$ associativity */
17 #define CONF1_DA_MASK   0x00000380
18 #define CONF1_DA_BASE   1
19 #define CONF1_DL_SHIFT  10                      /* D$ line size */
20 #define CONF1_DL_MASK   0x00001c00
21 #define CONF1_DL_BASE   2
22 #define CONF1_DS_SHIFT  13                      /* D$ sets/way */
23 #define CONF1_DS_MASK   0x0000e000
24 #define CONF1_DS_BASE   64
25 #define CONF1_IA_SHIFT  16                      /* I$ associativity */
26 #define CONF1_IA_MASK   0x00070000
27 #define CONF1_IA_BASE   1
28 #define CONF1_IL_SHIFT  19                      /* I$ line size */
29 #define CONF1_IL_MASK   0x00380000
30 #define CONF1_IL_BASE   2
31 #define CONF1_IS_SHIFT  22                      /* Instruction cache sets/way */
32 #define CONF1_IS_MASK   0x01c00000
33 #define CONF1_IS_BASE   64
35 #define CONF_AR         (7 << 10) 
37 #define Index_Invalidate_I      0x00
38 #define Index_Writeback_Inv_D   0x01
40         .text
41         LEAF(startup)
42         .set noreorder
43         addi    sp, -48
44         sw      a0, 16(sp)
45         sw      a1, 20(sp)
46         sw      a2, 24(sp)
47         sw      a3, 28(sp)
48         
49         /* Copy decompressor code to the right place */
50         li      t2, BZ_TEXT_START
51         add     a0, t2, 0
52         la      a1, code_start
53         la      a2, code_stop
54 $L1:
55         lw      t0, 0(a1)
56         sw      t0, 0(a0)
57         add     a1, 4
58         add     a0, 4
59         blt     a1, a2, $L1
60         nop
61         
62         /* At this point we need to invalidate dcache and */
63         /* icache before jumping to new code */
65 1:      /* Get cache sizes */
66         .set    mips32
67         mfc0    s0,C0_CONFIG,1
68         .set    mips0
70         li      s1,CONF1_DL_MASK
71         and     s1,s0
72         beq     s1,zero,nodc
73         nop
75         srl     s1,CONF1_DL_SHIFT
76         li      t0,CONF1_DL_BASE
77         sll     s1,t0,s1                /* s1 has D$ cache line size */
79         li      s2,CONF1_DA_MASK
80         and     s2,s0
81         srl     s2,CONF1_DA_SHIFT
82         addiu   s2,CONF1_DA_BASE        /* s2 now has D$ associativity */
84         li      t0,CONF1_DS_MASK
85         and     t0,s0
86         srl     t0,CONF1_DS_SHIFT
87         li      s3,CONF1_DS_BASE
88         sll     s3,s3,t0                /* s3 has D$ sets per way */
90         multu   s2,s3                   /* sets/way * associativity */
91         mflo    t0                      /* total cache lines */
93         multu   s1,t0                   /* D$ linesize * lines */
94         mflo    s2                      /* s2 is now D$ size in bytes */
96         /* Figure if it is a mips32r2 CPU which we take as an indication that
97          * there is no BRCM CP0 register and the D$ tags are in select 2
98          */
99         mfc0    s6,C0_CONFIG
100         andi    s6,CONF_AR                      # s6 != 0 if mips32r2
101         /* Initilize the D$: */
102         beqz    s6,1f
103         nop
104         .set    mips32
105         mtc0    zero,C0_TAGLO,2                 # For mips32r2 the D$ Tags are in select 2
106         mtc0    zero,C0_TAGHI,2
107         .set    mips0
108         b       2f
109         nop
112         mtc0    zero,C0_TAGLO
113         mtc0    zero,C0_TAGHI
116         li      t0,KSEG0                /* Just an address for the first $ line */
117         addu    t1,t0,s2                /*  + size of cache == end */
119         .set    mips3
120 3:      cache   Index_Writeback_Inv_D,0(t0)
121         .set    mips0
122         bne     t0,t1,3b
123         addu    t0,s1
124         
125 nodc:
126         /* Now we get to do it all again for the I$ */
127         
128         move    s3,zero                 /* just in case there is no icache */
129         move    s4,zero
131         li      t0,CONF1_IL_MASK
132         and     t0,s0
133         beq     t0,zero,noic
134         nop
136         srl     t0,CONF1_IL_SHIFT
137         li      s3,CONF1_IL_BASE
138         sll     s3,t0                   /* s3 has I$ cache line size */
140         li      t0,CONF1_IA_MASK
141         and     t0,s0
142         srl     t0,CONF1_IA_SHIFT
143         addiu   s4,t0,CONF1_IA_BASE     /* s4 now has I$ associativity */
145         li      t0,CONF1_IS_MASK
146         and     t0,s0
147         srl     t0,CONF1_IS_SHIFT
148         li      s5,CONF1_IS_BASE
149         sll     s5,t0                   /* s5 has I$ sets per way */
151         multu   s4,s5                   /* sets/way * associativity */
152         mflo    t0                      /* s4 is now total cache lines */
154         multu   s3,t0                   /* I$ linesize * lines */
155         mflo    s4                      /* s4 is cache size in bytes */
157         /* Initilize the I$: */
158         mtc0    zero,C0_TAGLO
159         mtc0    zero,C0_TAGHI
161         li      t0,KSEG0                /* Just an address for the first $ line */
162         addu    t1,t0,s4                /*  + size of cache == end */
164         .set    mips3
165 1:      cache   Index_Invalidate_I,0(t0)
166         .set    mips0
167         bne     t0,t1,1b
168         addu    t0,s3
170 noic:
171         move    a0,s3                   /* icache line size */
172         move    a1,s4                   /* icache size */
173         move    a2,s1                   /* dcache line size */
174         jal     t2
175         move    a3,s2                   /* dcache size */
176         
177         .set reorder
178         END(startup)