# HG changeset patch # User Paul Boddie # Date 1462392277 -7200 # Node ID 59eede5312e3e83c144f43ecd95ecb4d8a9afd94 # Parent 09b0fea027bdc546b5c72372b2441d0163614249 Moved almost all assembly language fragments into a separate file. diff -r 09b0fea027bd -r 59eede5312e3 stage2/Makefile --- a/stage2/Makefile Wed May 04 17:03:35 2016 +0200 +++ b/stage2/Makefile Wed May 04 22:04:37 2016 +0200 @@ -62,8 +62,8 @@ # Ordering of objects is important and cannot be left to replacement rules. -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) -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) +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) +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) .PHONY: all clean distclean diff -r 09b0fea027bd -r 59eede5312e3 stage2/cpu.c --- a/stage2/cpu.c Wed May 04 17:03:35 2016 +0200 +++ b/stage2/cpu.c Wed May 04 22:04:37 2016 +0200 @@ -23,51 +23,28 @@ */ #include "cpu.h" +#include "cpu_op.h" #include "sdram.h" #include "paging.h" void flush_icache_all(void) { - u32 addr, t = 0; + u32 addr; - asm volatile ("mtc0 $0, $28"); /* Clear Taglo */ - asm volatile ("mtc0 $0, $29"); /* Clear TagHi */ + flush_icache_tag(); - for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE; - addr += CONFIG_SYS_CACHELINE_SIZE) { - asm volatile ( - ".set mips3\n\t" - " cache %0, 0(%1)\n\t" - ".set mips2\n\t" - : - : "I" (Index_Store_Tag_I), "r"(addr)); - } + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE) + flush_icache_region(addr); - /* invalicate btb */ - asm volatile ( - ".set mips32\n\t" - "mfc0 %0, $16, 7\n\t" - "nop\n\t" - "ori %0,2\n\t" - "mtc0 %0, $16, 7\n\t" - ".set mips2\n\t" - : - : "r" (t)); + flush_icache_config(); } void flush_dcache_all(void) { u32 addr; - for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE; - addr += CONFIG_SYS_CACHELINE_SIZE) { - asm volatile ( - ".set mips3\n\t" - " cache %0, 0(%1)\n\t" - ".set mips2\n\t" - : - : "I" (Index_Writeback_Inv_D), "r"(addr)); - } + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE) + flush_dcache_region(addr); asm volatile ("sync"); } @@ -78,41 +55,6 @@ flush_icache_all(); } -void handle_error_level(void) -{ - asm volatile( - "mfc0 $t3, $12\n" /* CP0_STATUS */ - "li $t4, 0xfffffffb\n" /* ERL = 0 */ - "and $t3, $t3, $t4\n" - "mtc0 $t3, $12\n" - "nop\n"); -} - -void enable_interrupts(void) -{ - asm volatile( - "mfc0 $t3, $12\n" /* CP0_STATUS */ - "li $t4, 0x0000fc01\n" /* IE = enable interrupts */ - "or $t3, $t3, $t4\n" - "mtc0 $t3, $12\n" - "nop\n"); -} - -void init_interrupts(void) -{ - /* Set exception registers. */ - - asm volatile( - "mtc0 $zero, $18\n" /* CP0_WATCHLO */ - "li $t3, 0x00800000\n" /* IV = 1 (use 0x80000200 for interrupts) */ - "mtc0 $t3, $13\n" /* CP0_CAUSE */ - "mfc0 $t4, $12\n" /* CP0_STATUS */ - "li $t3, 0xffbfffff\n" /* BEV=0 */ - "and $t3, $t3, $t4\n" - "mtc0 $t3, $12\n" - "nop\n"); -} - void init_registers(u32 *base, u32 got, void (*function)(), u32 args[], u8 nargs) { u8 i; @@ -131,45 +73,9 @@ base[29] = (u32) function - 0x80000000; /* store the function address as EPC (for the handler) */ } -void invoke_task(u8 asid, u32 *base, u32 *stack_pointer) -{ - asm volatile( - "mtc0 %0, $10\n" /* CP0_ENTRYHI */ - "nop\n" - "move $t4, %1\n" /* use arguments before they are overwritten */ - "lw $sp, 0($t4)\n" /* set the stack pointer */ - "move $t3, %2\n" /* load parameters from the stored registers */ - "lw $a0, 16($t3)\n" - "lw $a1, 20($t3)\n" - "lw $a2, 24($t3)\n" - "lw $a3, 28($t3)\n" - "lw $t9, 100($t3)\n" - "lw $gp, 104($t3)\n" - "mtc0 $t9, $14\n" /* CP0_EPC */ - "mfc0 $t3, $12\n" /* CP0_STATUS */ - "ori $t3, $t3, 0x2\n" /* EXL = 1 */ - "mtc0 $t3, $12\n" /* CP0_STATUS */ - ".set mips3\n" - "eret\n" - ".set mips2\n" - "nop" - : - : "r" (asid), "r" (stack_pointer), "r" (base) - ); -} - void init_tlb(void) { - unsigned short first_random = 0, i, limit; - - asm volatile( - "mtc0 $zero, $4\n" /* CP0_CONTEXT */ - "mtc0 %1, $6\n" /* CP0_WIRED */ - "mfc0 %0, $16\n" /* CP0_CONFIG1 */ - "nop" - : "=r" (limit) - : "r" (first_random) - ); + u32 limit = configure_tlb(), i; /* Reset the mappings. The total number is bits 30..25 of Config1. */ @@ -186,28 +92,8 @@ u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags; u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1; - asm volatile( - "mtc0 %3, $5\n" /* CP0_PAGEMASK */ - - /* Set the index. */ - - "mtc0 %4, $0\n" /* CP0_INDEX */ - - /* Set physical address. */ - - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */ - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */ - - /* Set virtual address. */ - - "mtc0 %2, $10\n" /* CP0_ENTRYHI */ - "nop\n" - - "tlbwi\n" - "nop" - : - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask), "r" (index) - ); + map_page_set_index(index); + map_page_index_op(lower, upper, start, pagemask); } void init_page_table(u32 page_table, u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid) @@ -265,88 +151,5 @@ u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags; u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1; - asm volatile( - "mtc0 %3, $5\n" /* CP0_PAGEMASK */ - - /* Set physical address. */ - - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */ - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */ - - /* Set virtual address. */ - - "mtc0 %2, $10\n" /* CP0_ENTRYHI */ - "nop\n" - - "tlbwr\n" - "nop" - : - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask) - ); -} - -void map_page_miss(u32 physical, u32 pagesize, u8 flags) -{ - u32 lower = ((physical & 0xfffff000) >> 6) | flags; - u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags; - u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1; - - asm volatile( - "mtc0 %2, $5\n" /* CP0_PAGEMASK */ - - /* Set physical address. */ - - "mtc0 %0, $2\n" /* CP0_ENTRYLO0 */ - "mtc0 %1, $3\n" /* CP0_ENTRYLO1 */ - "nop\n" - - "tlbwr\n" - "nop" - : - : "r" (lower), "r" (upper), "r" (pagemask) - ); + map_page_op(lower, upper, start, pagemask); } - -void unmap_page(u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid) -{ - u32 start = (virtual & 0xffffe000) | asid; /* VPN2 | ASID*/ - u32 lower = ((physical & 0xfffff000) >> 6) | flags; - u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags; - u32 pagemask = ((pagesize - 1) & 0xfffff000) << 1; - u32 index = 0; - - asm volatile( - "mtc0 %4, $5\n" /* CP0_PAGEMASK */ - - /* Set physical address. */ - - "mtc0 %1, $2\n" /* CP0_ENTRYLO0 */ - "mtc0 %2, $3\n" /* CP0_ENTRYLO1 */ - - /* Set virtual address. */ - - "mtc0 %3, $10\n" /* CP0_ENTRYHI */ - "nop\n" - - /* Find an existing mapping. */ - - "tlbp\n" - "nop\n" - - /* Read the index register to see if a match was found. */ - - "mfc0 %0, $0\n" /* CP0_INDEX */ - "nop" - : "=r" (index) - : "r" (lower), "r" (upper), "r" (start), "r" (pagemask) - ); - - /* Return if the page is not mapped. */ - - if (index & 0x80000000) - return; - - /* Otherwise, invalidate the mapping. */ - - map_page_index(virtual, physical, pagesize, flags & 0xfd, asid, index); -} diff -r 09b0fea027bd -r 59eede5312e3 stage2/cpu.h --- a/stage2/cpu.h Wed May 04 17:03:35 2016 +0200 +++ b/stage2/cpu.h Wed May 04 22:04:37 2016 +0200 @@ -4,16 +4,10 @@ #include "xburst_types.h" void flush_cache_all(); -void handle_error_level(); void init_registers(u32 *, u32, void (*)(), u32[], u8); -void invoke_task(u8, u32 *, u32 *); -void enable_interrupts(); -void init_interrupts(); void init_tlb(); void map_page(u32, u32, u32, u8, u8); void init_page_table(u32, u32, u32, u32, u8, u8); -void map_page_miss(u32, u32, u8); void map_page_index(u32, u32, u32, u8, u8, u32); -void unmap_page(u32, u32, u32, u8, u8); #endif /* __CPU_H__ */ diff -r 09b0fea027bd -r 59eede5312e3 stage2/cpu_op.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/cpu_op.S Wed May 04 22:04:37 2016 +0200 @@ -0,0 +1,198 @@ +/* + * CPU-specific routines originally from U-Boot. + * See: uboot-xburst/files/arch/mips/cpu/xburst/cpu.c + * See: u-boot/arch/mips/include/asm/cacheops.h + * + * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, + * Copyright (C) 2015, 2016 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include "mips.h" +#include "paging.h" +#include "sdram.h" + +.text +.globl flush_icache_tag +.globl flush_icache_region +.globl flush_icache_config +.globl flush_dcache_region +.globl handle_error_level +.globl enable_interrupts +.globl init_interrupts +.globl invoke_task +.globl configure_tlb +.globl map_page_set_index +.globl map_page_index_op +.globl map_page_op +.set noreorder + + + +flush_icache_tag: + mtc0 $zero, CP0_TAGLO + mtc0 $zero, CP0_TAGHI + jr $ra + nop + + + +flush_icache_region: + cache Index_Store_Tag_I, 0($a0) + jr $ra + nop + + + +flush_icache_config: + move $t3, $zero + mfc0 $t3, CP0_CONFIG, 7 + nop + ori $t3, 2 + mtc0 $t3, CP0_CONFIG, 7 + jr $ra + nop + + + +flush_dcache_region: + cache Index_Writeback_Inv_D, 0($a0) + jr $ra + nop + + + +handle_error_level: + mfc0 $t3, CP0_STATUS + li $t4, 0xfffffffb /* ERL = 0 */ + and $t3, $t3, $t4 + mtc0 $t3, CP0_STATUS + jr $ra + nop + + + +enable_interrupts: + mfc0 $t3, CP0_STATUS + li $t4, 0x0000fc01 /* IE = enable interrupts */ + or $t3, $t3, $t4 + mtc0 $t3, CP0_STATUS + jr $ra + nop + + + +init_interrupts: + + /* Set exception registers. */ + + mtc0 $zero, CP0_WATCHLO + li $t3, 0x00800000 /* IV = 1 (use 0x80000200 for interrupts) */ + mtc0 $t3, CP0_CAUSE + mfc0 $t4, CP0_STATUS + li $t3, 0xffbfffff /* BEV=0 */ + and $t3, $t3, $t4 + mtc0 $t3, CP0_STATUS + jr $ra + nop + + + +/* (u8 asid, u32 *base, u32 *stack_pointer) */ + +invoke_task: + mtc0 $a0, CP0_ENTRYHI + nop + move $t4, $a2 /* use arguments before they are overwritten */ + lw $sp, 0($t4) /* set the stack pointer */ + move $t3, $a1 /* load parameters from the stored registers */ + lw $a0, 16($t3) + lw $a1, 20($t3) + lw $a2, 24($t3) + lw $a3, 28($t3) + lw $t9, 100($t3) + lw $gp, 104($t3) + mtc0 $t9, CP0_EPC + mfc0 $t3, CP0_STATUS + ori $t3, $t3, 0x2 /* EXL = 1 */ + mtc0 $t3, CP0_STATUS + eret + nop + + + +configure_tlb: + mtc0 $zero, CP0_CONTEXT + mtc0 $zero, CP0_WIRED /* first random entry is zero */ + mfc0 $v0, CP0_CONFIG /* return the limit */ + jr $ra + nop + + + +/* (u32 index) */ + +map_page_set_index: + mtc0 $a0, CP0_INDEX + jr $ra + nop + + + +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */ + +map_page_index_op: + jal map_page_op_setup + nop + + tlbwi + jr $ra + nop + + + +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */ + +map_page_op: + jal map_page_op_setup + nop + + tlbwr + jr $ra + nop + + + +/* (u32 lower, u32 upper, u32 start, u32 pagemask) */ + +map_page_op_setup: + mtc0 $a3, CP0_PAGEMASK + + /* Set physical address. */ + + mtc0 $a0, CP0_ENTRYLO0 + mtc0 $a1, CP0_ENTRYLO1 + + /* Set virtual address. */ + + mtc0 $a2, CP0_ENTRYHI + jr $ra + nop + + + +.set reorder diff -r 09b0fea027bd -r 59eede5312e3 stage2/cpu_op.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/cpu_op.h Wed May 04 22:04:37 2016 +0200 @@ -0,0 +1,19 @@ +#ifndef __CPU_OP_H__ +#define __CPU_OP_H__ + +#include "xburst_types.h" + +void flush_icache_tag(); +void flush_icache_region(u32); +void flush_icache_config(); +void flush_dcache_region(u32); +void handle_error_level(); +void enable_interrupts(); +void init_interrupts(); +void invoke_task(u8, u32 *, u32 *); +u32 configure_tlb(); +void map_page_set_index(u32); +void map_page_op(u32, u32, u32, u32); +void map_page_index_op(u32, u32, u32, u32); + +#endif /* __CPU_OP_H__ */ diff -r 09b0fea027bd -r 59eede5312e3 stage2/irq.c --- a/stage2/irq.c Wed May 04 17:03:35 2016 +0200 +++ b/stage2/irq.c Wed May 04 22:04:37 2016 +0200 @@ -22,6 +22,7 @@ #include "init.h" #include "board.h" #include "cpu.h" +#include "cpu_op.h" #include "irq.h" #include "tasks.h" diff -r 09b0fea027bd -r 59eede5312e3 stage2/stage2.c --- a/stage2/stage2.c Wed May 04 17:03:35 2016 +0200 +++ b/stage2/stage2.c Wed May 04 22:04:37 2016 +0200 @@ -22,6 +22,7 @@ #include "irq.h" #include "lcd.h" #include "cpu.h" +#include "cpu_op.h" #include "tasks.h" #include "example.h" diff -r 09b0fea027bd -r 59eede5312e3 stage2/tasks.c --- a/stage2/tasks.c Wed May 04 17:03:35 2016 +0200 +++ b/stage2/tasks.c Wed May 04 22:04:37 2016 +0200 @@ -18,6 +18,7 @@ */ #include "cpu.h" +#include "cpu_op.h" #include "paging.h" #include "tasks.h"