1.1 --- a/stage2/Makefile Wed May 04 17:03:35 2016 +0200
1.2 +++ b/stage2/Makefile Wed May 04 22:04:37 2016 +0200
1.3 @@ -62,8 +62,8 @@
1.4
1.5 # Ordering of objects is important and cannot be left to replacement rules.
1.6
1.7 -SRC = head2.S entry.S handlers.S stage2.c cpu.c lcd.c jzlcd.c board.c irq.c tasks.c example.c $(BOARD_SRC)
1.8 -OBJ = head2.o entry.o handlers.o stage2.o cpu.o lcd.o jzlcd.o board.o irq.o tasks.o example.o $(BOARD_OBJ)
1.9 +SRC = head2.S entry.S handlers.S stage2.c cpu.c cpu_op.S lcd.c jzlcd.c board.c irq.c tasks.c example.c $(BOARD_SRC)
1.10 +OBJ = head2.o entry.o handlers.o stage2.o cpu.o cpu_op.o lcd.o jzlcd.o board.o irq.o tasks.o example.o $(BOARD_OBJ)
1.11
1.12 .PHONY: all clean distclean
1.13
2.1 --- a/stage2/cpu.c Wed May 04 17:03:35 2016 +0200
2.2 +++ b/stage2/cpu.c Wed May 04 22:04:37 2016 +0200
2.3 @@ -23,51 +23,28 @@
2.4 */
2.5
2.6 #include "cpu.h"
2.7 +#include "cpu_op.h"
2.8 #include "sdram.h"
2.9 #include "paging.h"
2.10
2.11 void flush_icache_all(void)
2.12 {
2.13 - u32 addr, t = 0;
2.14 + u32 addr;
2.15
2.16 - asm volatile ("mtc0 $0, $28"); /* Clear Taglo */
2.17 - asm volatile ("mtc0 $0, $29"); /* Clear TagHi */
2.18 + flush_icache_tag();
2.19
2.20 - for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE;
2.21 - addr += CONFIG_SYS_CACHELINE_SIZE) {
2.22 - asm volatile (
2.23 - ".set mips3\n\t"
2.24 - " cache %0, 0(%1)\n\t"
2.25 - ".set mips2\n\t"
2.26 - :
2.27 - : "I" (Index_Store_Tag_I), "r"(addr));
2.28 - }
2.29 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE)
2.30 + flush_icache_region(addr);
2.31
2.32 - /* invalicate btb */
2.33 - asm volatile (
2.34 - ".set mips32\n\t"
2.35 - "mfc0 %0, $16, 7\n\t"
2.36 - "nop\n\t"
2.37 - "ori %0,2\n\t"
2.38 - "mtc0 %0, $16, 7\n\t"
2.39 - ".set mips2\n\t"
2.40 - :
2.41 - : "r" (t));
2.42 + flush_icache_config();
2.43 }
2.44
2.45 void flush_dcache_all(void)
2.46 {
2.47 u32 addr;
2.48
2.49 - for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE;
2.50 - addr += CONFIG_SYS_CACHELINE_SIZE) {
2.51 - asm volatile (
2.52 - ".set mips3\n\t"
2.53 - " cache %0, 0(%1)\n\t"
2.54 - ".set mips2\n\t"
2.55 - :
2.56 - : "I" (Index_Writeback_Inv_D), "r"(addr));
2.57 - }
2.58 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE)
2.59 + flush_dcache_region(addr);
2.60
2.61 asm volatile ("sync");
2.62 }
2.63 @@ -78,41 +55,6 @@
2.64 flush_icache_all();
2.65 }
2.66
2.67 -void handle_error_level(void)
2.68 -{
2.69 - asm volatile(
2.70 - "mfc0 $t3, $12\n" /* CP0_STATUS */
2.71 - "li $t4, 0xfffffffb\n" /* ERL = 0 */
2.72 - "and $t3, $t3, $t4\n"
2.73 - "mtc0 $t3, $12\n"
2.74 - "nop\n");
2.75 -}
2.76 -
2.77 -void enable_interrupts(void)
2.78 -{
2.79 - asm volatile(
2.80 - "mfc0 $t3, $12\n" /* CP0_STATUS */
2.81 - "li $t4, 0x0000fc01\n" /* IE = enable interrupts */
2.82 - "or $t3, $t3, $t4\n"
2.83 - "mtc0 $t3, $12\n"
2.84 - "nop\n");
2.85 -}
2.86 -
2.87 -void init_interrupts(void)
2.88 -{
2.89 - /* Set exception registers. */
2.90 -
2.91 - asm volatile(
2.92 - "mtc0 $zero, $18\n" /* CP0_WATCHLO */
2.93 - "li $t3, 0x00800000\n" /* IV = 1 (use 0x80000200 for interrupts) */
2.94 - "mtc0 $t3, $13\n" /* CP0_CAUSE */
2.95 - "mfc0 $t4, $12\n" /* CP0_STATUS */
2.96 - "li $t3, 0xffbfffff\n" /* BEV=0 */
2.97 - "and $t3, $t3, $t4\n"
2.98 - "mtc0 $t3, $12\n"
2.99 - "nop\n");
2.100 -}
2.101 -
2.102 void init_registers(u32 *base, u32 got, void (*function)(), u32 args[], u8 nargs)
2.103 {
2.104 u8 i;
2.105 @@ -131,45 +73,9 @@
2.106 base[29] = (u32) function - 0x80000000; /* store the function address as EPC (for the handler) */
2.107 }
2.108
2.109 -void invoke_task(u8 asid, u32 *base, u32 *stack_pointer)
2.110 -{
2.111 - asm volatile(
2.112 - "mtc0 %0, $10\n" /* CP0_ENTRYHI */
2.113 - "nop\n"
2.114 - "move $t4, %1\n" /* use arguments before they are overwritten */
2.115 - "lw $sp, 0($t4)\n" /* set the stack pointer */
2.116 - "move $t3, %2\n" /* load parameters from the stored registers */
2.117 - "lw $a0, 16($t3)\n"
2.118 - "lw $a1, 20($t3)\n"
2.119 - "lw $a2, 24($t3)\n"
2.120 - "lw $a3, 28($t3)\n"
2.121 - "lw $t9, 100($t3)\n"
2.122 - "lw $gp, 104($t3)\n"
2.123 - "mtc0 $t9, $14\n" /* CP0_EPC */
2.124 - "mfc0 $t3, $12\n" /* CP0_STATUS */
2.125 - "ori $t3, $t3, 0x2\n" /* EXL = 1 */
2.126 - "mtc0 $t3, $12\n" /* CP0_STATUS */
2.127 - ".set mips3\n"
2.128 - "eret\n"
2.129 - ".set mips2\n"
2.130 - "nop"
2.131 - :
2.132 - : "r" (asid), "r" (stack_pointer), "r" (base)
2.133 - );
2.134 -}
2.135 -
2.136 void init_tlb(void)
2.137 {
2.138 - unsigned short first_random = 0, i, limit;
2.139 -
2.140 - asm volatile(
2.141 - "mtc0 $zero, $4\n" /* CP0_CONTEXT */
2.142 - "mtc0 %1, $6\n" /* CP0_WIRED */
2.143 - "mfc0 %0, $16\n" /* CP0_CONFIG1 */
2.144 - "nop"
2.145 - : "=r" (limit)
2.146 - : "r" (first_random)
2.147 - );
2.148 + u32 limit = configure_tlb(), i;
2.149
2.150 /* Reset the mappings. The total number is bits 30..25 of Config1. */
2.151
2.152 @@ -186,28 +92,8 @@
2.153 u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags;
2.154 u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1;
2.155
2.156 - asm volatile(
2.157 - "mtc0 %3, $5\n" /* CP0_PAGEMASK */
2.158 -
2.159 - /* Set the index. */
2.160 -
2.161 - "mtc0 %4, $0\n" /* CP0_INDEX */
2.162 -
2.163 - /* Set physical address. */
2.164 -
2.165 - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */
2.166 - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */
2.167 -
2.168 - /* Set virtual address. */
2.169 -
2.170 - "mtc0 %2, $10\n" /* CP0_ENTRYHI */
2.171 - "nop\n"
2.172 -
2.173 - "tlbwi\n"
2.174 - "nop"
2.175 - :
2.176 - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask), "r" (index)
2.177 - );
2.178 + map_page_set_index(index);
2.179 + map_page_index_op(lower, upper, start, pagemask);
2.180 }
2.181
2.182 void init_page_table(u32 page_table, u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid)
2.183 @@ -265,88 +151,5 @@
2.184 u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags;
2.185 u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1;
2.186
2.187 - asm volatile(
2.188 - "mtc0 %3, $5\n" /* CP0_PAGEMASK */
2.189 -
2.190 - /* Set physical address. */
2.191 -
2.192 - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */
2.193 - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */
2.194 -
2.195 - /* Set virtual address. */
2.196 -
2.197 - "mtc0 %2, $10\n" /* CP0_ENTRYHI */
2.198 - "nop\n"
2.199 -
2.200 - "tlbwr\n"
2.201 - "nop"
2.202 - :
2.203 - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask)
2.204 - );
2.205 -}
2.206 -
2.207 -void map_page_miss(u32 physical, u32 pagesize, u8 flags)
2.208 -{
2.209 - u32 lower = ((physical & 0xfffff000) >> 6) | flags;
2.210 - u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags;
2.211 - u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1;
2.212 -
2.213 - asm volatile(
2.214 - "mtc0 %2, $5\n" /* CP0_PAGEMASK */
2.215 -
2.216 - /* Set physical address. */
2.217 -
2.218 - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */
2.219 - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */
2.220 - "nop\n"
2.221 -
2.222 - "tlbwr\n"
2.223 - "nop"
2.224 - :
2.225 - : "r" (lower), "r" (upper), "r" (pagemask)
2.226 - );
2.227 + map_page_op(lower, upper, start, pagemask);
2.228 }
2.229 -
2.230 -void unmap_page(u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid)
2.231 -{
2.232 - u32 start = (virtual & 0xffffe000) | asid; /* VPN2 | ASID*/
2.233 - u32 lower = ((physical & 0xfffff000) >> 6) | flags;
2.234 - u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags;
2.235 - u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1;
2.236 - u32 index = 0;
2.237 -
2.238 - asm volatile(
2.239 - "mtc0 %4, $5\n" /* CP0_PAGEMASK */
2.240 -
2.241 - /* Set physical address. */
2.242 -
2.243 - "mtc0 %1, $2\n" /* CP0_ENTRYLO0 */
2.244 - "mtc0 %2, $3\n" /* CP0_ENTRYLO1 */
2.245 -
2.246 - /* Set virtual address. */
2.247 -
2.248 - "mtc0 %3, $10\n" /* CP0_ENTRYHI */
2.249 - "nop\n"
2.250 -
2.251 - /* Find an existing mapping. */
2.252 -
2.253 - "tlbp\n"
2.254 - "nop\n"
2.255 -
2.256 - /* Read the index register to see if a match was found. */
2.257 -
2.258 - "mfc0 %0, $0\n" /* CP0_INDEX */
2.259 - "nop"
2.260 - : "=r" (index)
2.261 - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask)
2.262 - );
2.263 -
2.264 - /* Return if the page is not mapped. */
2.265 -
2.266 - if (index & 0x80000000)
2.267 - return;
2.268 -
2.269 - /* Otherwise, invalidate the mapping. */
2.270 -
2.271 - map_page_index(virtual, physical, pagesize, flags & 0xfd, asid, index);
2.272 -}
3.1 --- a/stage2/cpu.h Wed May 04 17:03:35 2016 +0200
3.2 +++ b/stage2/cpu.h Wed May 04 22:04:37 2016 +0200
3.3 @@ -4,16 +4,10 @@
3.4 #include "xburst_types.h"
3.5
3.6 void flush_cache_all();
3.7 -void handle_error_level();
3.8 void init_registers(u32 *, u32, void (*)(), u32[], u8);
3.9 -void invoke_task(u8, u32 *, u32 *);
3.10 -void enable_interrupts();
3.11 -void init_interrupts();
3.12 void init_tlb();
3.13 void map_page(u32, u32, u32, u8, u8);
3.14 void init_page_table(u32, u32, u32, u32, u8, u8);
3.15 -void map_page_miss(u32, u32, u8);
3.16 void map_page_index(u32, u32, u32, u8, u8, u32);
3.17 -void unmap_page(u32, u32, u32, u8, u8);
3.18
3.19 #endif /* __CPU_H__ */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/stage2/cpu_op.S Wed May 04 22:04:37 2016 +0200
4.3 @@ -0,0 +1,198 @@
4.4 +/*
4.5 + * CPU-specific routines originally from U-Boot.
4.6 + * See: uboot-xburst/files/arch/mips/cpu/xburst/cpu.c
4.7 + * See: u-boot/arch/mips/include/asm/cacheops.h
4.8 + *
4.9 + * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
4.10 + * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
4.11 + *
4.12 + * This program is free software; you can redistribute it and/or
4.13 + * modify it under the terms of the GNU General Public License as
4.14 + * published by the Free Software Foundation; either version 2 of
4.15 + * the License, or (at your option) any later version.
4.16 + *
4.17 + * This program is distributed in the hope that it will be useful,
4.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.20 + * GNU General Public License for more details.
4.21 + *
4.22 + * You should have received a copy of the GNU General Public License
4.23 + * along with this program; if not, write to the Free Software
4.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
4.25 + * Boston, MA 02110-1301, USA
4.26 + */
4.27 +
4.28 +#include "mips.h"
4.29 +#include "paging.h"
4.30 +#include "sdram.h"
4.31 +
4.32 +.text
4.33 +.globl flush_icache_tag
4.34 +.globl flush_icache_region
4.35 +.globl flush_icache_config
4.36 +.globl flush_dcache_region
4.37 +.globl handle_error_level
4.38 +.globl enable_interrupts
4.39 +.globl init_interrupts
4.40 +.globl invoke_task
4.41 +.globl configure_tlb
4.42 +.globl map_page_set_index
4.43 +.globl map_page_index_op
4.44 +.globl map_page_op
4.45 +.set noreorder
4.46 +
4.47 +
4.48 +
4.49 +flush_icache_tag:
4.50 + mtc0 $zero, CP0_TAGLO
4.51 + mtc0 $zero, CP0_TAGHI
4.52 + jr $ra
4.53 + nop
4.54 +
4.55 +
4.56 +
4.57 +flush_icache_region:
4.58 + cache Index_Store_Tag_I, 0($a0)
4.59 + jr $ra
4.60 + nop
4.61 +
4.62 +
4.63 +
4.64 +flush_icache_config:
4.65 + move $t3, $zero
4.66 + mfc0 $t3, CP0_CONFIG, 7
4.67 + nop
4.68 + ori $t3, 2
4.69 + mtc0 $t3, CP0_CONFIG, 7
4.70 + jr $ra
4.71 + nop
4.72 +
4.73 +
4.74 +
4.75 +flush_dcache_region:
4.76 + cache Index_Writeback_Inv_D, 0($a0)
4.77 + jr $ra
4.78 + nop
4.79 +
4.80 +
4.81 +
4.82 +handle_error_level:
4.83 + mfc0 $t3, CP0_STATUS
4.84 + li $t4, 0xfffffffb /* ERL = 0 */
4.85 + and $t3, $t3, $t4
4.86 + mtc0 $t3, CP0_STATUS
4.87 + jr $ra
4.88 + nop
4.89 +
4.90 +
4.91 +
4.92 +enable_interrupts:
4.93 + mfc0 $t3, CP0_STATUS
4.94 + li $t4, 0x0000fc01 /* IE = enable interrupts */
4.95 + or $t3, $t3, $t4
4.96 + mtc0 $t3, CP0_STATUS
4.97 + jr $ra
4.98 + nop
4.99 +
4.100 +
4.101 +
4.102 +init_interrupts:
4.103 +
4.104 + /* Set exception registers. */
4.105 +
4.106 + mtc0 $zero, CP0_WATCHLO
4.107 + li $t3, 0x00800000 /* IV = 1 (use 0x80000200 for interrupts) */
4.108 + mtc0 $t3, CP0_CAUSE
4.109 + mfc0 $t4, CP0_STATUS
4.110 + li $t3, 0xffbfffff /* BEV=0 */
4.111 + and $t3, $t3, $t4
4.112 + mtc0 $t3, CP0_STATUS
4.113 + jr $ra
4.114 + nop
4.115 +
4.116 +
4.117 +
4.118 +/* (u8 asid, u32 *base, u32 *stack_pointer) */
4.119 +
4.120 +invoke_task:
4.121 + mtc0 $a0, CP0_ENTRYHI
4.122 + nop
4.123 + move $t4, $a2 /* use arguments before they are overwritten */
4.124 + lw $sp, 0($t4) /* set the stack pointer */
4.125 + move $t3, $a1 /* load parameters from the stored registers */
4.126 + lw $a0, 16($t3)
4.127 + lw $a1, 20($t3)
4.128 + lw $a2, 24($t3)
4.129 + lw $a3, 28($t3)
4.130 + lw $t9, 100($t3)
4.131 + lw $gp, 104($t3)
4.132 + mtc0 $t9, CP0_EPC
4.133 + mfc0 $t3, CP0_STATUS
4.134 + ori $t3, $t3, 0x2 /* EXL = 1 */
4.135 + mtc0 $t3, CP0_STATUS
4.136 + eret
4.137 + nop
4.138 +
4.139 +
4.140 +
4.141 +configure_tlb:
4.142 + mtc0 $zero, CP0_CONTEXT
4.143 + mtc0 $zero, CP0_WIRED /* first random entry is zero */
4.144 + mfc0 $v0, CP0_CONFIG /* return the limit */
4.145 + jr $ra
4.146 + nop
4.147 +
4.148 +
4.149 +
4.150 +/* (u32 index) */
4.151 +
4.152 +map_page_set_index:
4.153 + mtc0 $a0, CP0_INDEX
4.154 + jr $ra
4.155 + nop
4.156 +
4.157 +
4.158 +
4.159 +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */
4.160 +
4.161 +map_page_index_op:
4.162 + jal map_page_op_setup
4.163 + nop
4.164 +
4.165 + tlbwi
4.166 + jr $ra
4.167 + nop
4.168 +
4.169 +
4.170 +
4.171 +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */
4.172 +
4.173 +map_page_op:
4.174 + jal map_page_op_setup
4.175 + nop
4.176 +
4.177 + tlbwr
4.178 + jr $ra
4.179 + nop
4.180 +
4.181 +
4.182 +
4.183 +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */
4.184 +
4.185 +map_page_op_setup:
4.186 + mtc0 $a3, CP0_PAGEMASK
4.187 +
4.188 + /* Set physical address. */
4.189 +
4.190 + mtc0 $a0, CP0_ENTRYLO0
4.191 + mtc0 $a1, CP0_ENTRYLO1
4.192 +
4.193 + /* Set virtual address. */
4.194 +
4.195 + mtc0 $a2, CP0_ENTRYHI
4.196 + jr $ra
4.197 + nop
4.198 +
4.199 +
4.200 +
4.201 +.set reorder
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/stage2/cpu_op.h Wed May 04 22:04:37 2016 +0200
5.3 @@ -0,0 +1,19 @@
5.4 +#ifndef __CPU_OP_H__
5.5 +#define __CPU_OP_H__
5.6 +
5.7 +#include "xburst_types.h"
5.8 +
5.9 +void flush_icache_tag();
5.10 +void flush_icache_region(u32);
5.11 +void flush_icache_config();
5.12 +void flush_dcache_region(u32);
5.13 +void handle_error_level();
5.14 +void enable_interrupts();
5.15 +void init_interrupts();
5.16 +void invoke_task(u8, u32 *, u32 *);
5.17 +u32 configure_tlb();
5.18 +void map_page_set_index(u32);
5.19 +void map_page_op(u32, u32, u32, u32);
5.20 +void map_page_index_op(u32, u32, u32, u32);
5.21 +
5.22 +#endif /* __CPU_OP_H__ */
6.1 --- a/stage2/irq.c Wed May 04 17:03:35 2016 +0200
6.2 +++ b/stage2/irq.c Wed May 04 22:04:37 2016 +0200
6.3 @@ -22,6 +22,7 @@
6.4 #include "init.h"
6.5 #include "board.h"
6.6 #include "cpu.h"
6.7 +#include "cpu_op.h"
6.8 #include "irq.h"
6.9 #include "tasks.h"
6.10
7.1 --- a/stage2/stage2.c Wed May 04 17:03:35 2016 +0200
7.2 +++ b/stage2/stage2.c Wed May 04 22:04:37 2016 +0200
7.3 @@ -22,6 +22,7 @@
7.4 #include "irq.h"
7.5 #include "lcd.h"
7.6 #include "cpu.h"
7.7 +#include "cpu_op.h"
7.8 #include "tasks.h"
7.9 #include "example.h"
7.10
8.1 --- a/stage2/tasks.c Wed May 04 17:03:35 2016 +0200
8.2 +++ b/stage2/tasks.c Wed May 04 22:04:37 2016 +0200
8.3 @@ -18,6 +18,7 @@
8.4 */
8.5
8.6 #include "cpu.h"
8.7 +#include "cpu_op.h"
8.8 #include "paging.h"
8.9 #include "tasks.h"
8.10