diff options
Diffstat (limited to 'ANDROID_3.4.5/arch/openrisc/kernel')
21 files changed, 0 insertions, 5602 deletions
diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/Makefile b/ANDROID_3.4.5/arch/openrisc/kernel/Makefile deleted file mode 100644 index 9a4c2706..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for the linux kernel. -# - -extra-y := head.o vmlinux.lds init_task.o - -obj-y := setup.o idle.o or32_ksyms.o process.o dma.o \ - traps.o time.o irq.o entry.o ptrace.o signal.o sys_or32.o \ - sys_call_table.o - -obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_OF) += prom.o - -clean: diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/asm-offsets.c b/ANDROID_3.4.5/arch/openrisc/kernel/asm-offsets.c deleted file mode 100644 index 1a242a0d..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/asm-offsets.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * OpenRISC asm-offsets.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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 used to generate definitions needed by - * assembly language modules. - * - * We use the technique used in the OSF Mach kernel code: - * generate asm statements containing #defines, - * compile this file to assembler, and then extract the - * #defines from the assembly-language output. - */ - -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/ptrace.h> -#include <linux/mman.h> -#include <linux/mm.h> -#include <linux/io.h> -#include <linux/thread_info.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/processor.h> - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define BLANK() asm volatile("\n->" : : ) - -int main(void) -{ - /* offsets into the task_struct */ - DEFINE(TASK_STATE, offsetof(struct task_struct, state)); - DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); - DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); - DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); - - /* offsets into thread_info */ - DEFINE(TI_TASK, offsetof(struct thread_info, task)); - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); - DEFINE(TI_KSP, offsetof(struct thread_info, ksp)); - - DEFINE(PT_SIZE, sizeof(struct pt_regs)); - - /* Interrupt register frame */ - DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); - DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); - - DEFINE(NUM_USER_SEGMENTS, TASK_SIZE >> 28); - return 0; -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/dma.c b/ANDROID_3.4.5/arch/openrisc/kernel/dma.c deleted file mode 100644 index f1c8ee28..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/dma.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * OpenRISC Linux - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - * - * DMA mapping callbacks... - * As alloc_coherent is the only DMA callback being used currently, that's - * the only thing implemented properly. The rest need looking into... - */ - -#include <linux/dma-mapping.h> -#include <linux/dma-debug.h> - -#include <asm/cpuinfo.h> -#include <asm/spr_defs.h> -#include <asm/tlbflush.h> - -static int page_set_nocache(pte_t *pte, unsigned long addr, - unsigned long next, struct mm_walk *walk) -{ - unsigned long cl; - - pte_val(*pte) |= _PAGE_CI; - - /* - * Flush the page out of the TLB so that the new page flags get - * picked up next time there's an access - */ - flush_tlb_page(NULL, addr); - - /* Flush page out of dcache */ - for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo.dcache_block_size) - mtspr(SPR_DCBFR, cl); - - return 0; -} - -static int page_clear_nocache(pte_t *pte, unsigned long addr, - unsigned long next, struct mm_walk *walk) -{ - pte_val(*pte) &= ~_PAGE_CI; - - /* - * Flush the page out of the TLB so that the new page flags get - * picked up next time there's an access - */ - flush_tlb_page(NULL, addr); - - return 0; -} - -/* - * Alloc "coherent" memory, which for OpenRISC means simply uncached. - * - * This function effectively just calls __get_free_pages, sets the - * cache-inhibit bit on those pages, and makes sure that the pages are - * flushed out of the cache before they are used. - * - */ -void *or1k_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) -{ - unsigned long va; - void *page; - struct mm_walk walk = { - .pte_entry = page_set_nocache, - .mm = &init_mm - }; - - page = alloc_pages_exact(size, gfp); - if (!page) - return NULL; - - /* This gives us the real physical address of the first page. */ - *dma_handle = __pa(page); - - va = (unsigned long)page; - - /* - * We need to iterate through the pages, clearing the dcache for - * them and setting the cache-inhibit bit. - */ - if (walk_page_range(va, va + size, &walk)) { - free_pages_exact(page, size); - return NULL; - } - - return (void *)va; -} - -void or1k_dma_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle) -{ - unsigned long va = (unsigned long)vaddr; - struct mm_walk walk = { - .pte_entry = page_clear_nocache, - .mm = &init_mm - }; - - /* walk_page_range shouldn't be able to fail here */ - WARN_ON(walk_page_range(va, va + size, &walk)); - - free_pages_exact(vaddr, size); -} - -dma_addr_t or1k_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - unsigned long cl; - dma_addr_t addr = page_to_phys(page) + offset; - - switch (dir) { - case DMA_TO_DEVICE: - /* Flush the dcache for the requested range */ - for (cl = addr; cl < addr + size; - cl += cpuinfo.dcache_block_size) - mtspr(SPR_DCBFR, cl); - break; - case DMA_FROM_DEVICE: - /* Invalidate the dcache for the requested range */ - for (cl = addr; cl < addr + size; - cl += cpuinfo.dcache_block_size) - mtspr(SPR_DCBIR, cl); - break; - default: - /* - * NOTE: If dir == DMA_BIDIRECTIONAL then there's no need to - * flush nor invalidate the cache here as the area will need - * to be manually synced anyway. - */ - break; - } - - return addr; -} - -void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - /* Nothing special to do here... */ -} - -int or1k_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct scatterlist *s; - int i; - - for_each_sg(sg, s, nents, i) { - s->dma_address = or1k_map_page(dev, sg_page(s), s->offset, - s->length, dir, NULL); - } - - return nents; -} - -void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct scatterlist *s; - int i; - - for_each_sg(sg, s, nents, i) { - or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL); - } -} - -void or1k_sync_single_for_cpu(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) -{ - unsigned long cl; - dma_addr_t addr = dma_handle; - - /* Invalidate the dcache for the requested range */ - for (cl = addr; cl < addr + size; cl += cpuinfo.dcache_block_size) - mtspr(SPR_DCBIR, cl); -} - -void or1k_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) -{ - unsigned long cl; - dma_addr_t addr = dma_handle; - - /* Flush the dcache for the requested range */ - for (cl = addr; cl < addr + size; cl += cpuinfo.dcache_block_size) - mtspr(SPR_DCBFR, cl); -} - -/* Number of entries preallocated for DMA-API debugging */ -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) - -static int __init dma_init(void) -{ - dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); - - return 0; -} -fs_initcall(dma_init); diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/entry.S b/ANDROID_3.4.5/arch/openrisc/kernel/entry.S deleted file mode 100644 index 6e61af86..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/entry.S +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * OpenRISC entry.S - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2005 Gyorgy Jeney <nog@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/linkage.h> - -#include <asm/processor.h> -#include <asm/unistd.h> -#include <asm/thread_info.h> -#include <asm/errno.h> -#include <asm/spr_defs.h> -#include <asm/page.h> -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/asm-offsets.h> - -#define DISABLE_INTERRUPTS(t1,t2) \ - l.mfspr t2,r0,SPR_SR ;\ - l.movhi t1,hi(~(SPR_SR_IEE|SPR_SR_TEE)) ;\ - l.ori t1,t1,lo(~(SPR_SR_IEE|SPR_SR_TEE)) ;\ - l.and t2,t2,t1 ;\ - l.mtspr r0,t2,SPR_SR - -#define ENABLE_INTERRUPTS(t1) \ - l.mfspr t1,r0,SPR_SR ;\ - l.ori t1,t1,lo(SPR_SR_IEE|SPR_SR_TEE) ;\ - l.mtspr r0,t1,SPR_SR - -/* =========================================================[ macros ]=== */ - -/* - * We need to disable interrupts at beginning of RESTORE_ALL - * since interrupt might come in after we've loaded EPC return address - * and overwrite EPC with address somewhere in RESTORE_ALL - * which is of course wrong! - */ - -#define RESTORE_ALL \ - DISABLE_INTERRUPTS(r3,r4) ;\ - l.lwz r3,PT_PC(r1) ;\ - l.mtspr r0,r3,SPR_EPCR_BASE ;\ - l.lwz r3,PT_SR(r1) ;\ - l.mtspr r0,r3,SPR_ESR_BASE ;\ - l.lwz r2,PT_GPR2(r1) ;\ - l.lwz r3,PT_GPR3(r1) ;\ - l.lwz r4,PT_GPR4(r1) ;\ - l.lwz r5,PT_GPR5(r1) ;\ - l.lwz r6,PT_GPR6(r1) ;\ - l.lwz r7,PT_GPR7(r1) ;\ - l.lwz r8,PT_GPR8(r1) ;\ - l.lwz r9,PT_GPR9(r1) ;\ - l.lwz r10,PT_GPR10(r1) ;\ - l.lwz r11,PT_GPR11(r1) ;\ - l.lwz r12,PT_GPR12(r1) ;\ - l.lwz r13,PT_GPR13(r1) ;\ - l.lwz r14,PT_GPR14(r1) ;\ - l.lwz r15,PT_GPR15(r1) ;\ - l.lwz r16,PT_GPR16(r1) ;\ - l.lwz r17,PT_GPR17(r1) ;\ - l.lwz r18,PT_GPR18(r1) ;\ - l.lwz r19,PT_GPR19(r1) ;\ - l.lwz r20,PT_GPR20(r1) ;\ - l.lwz r21,PT_GPR21(r1) ;\ - l.lwz r22,PT_GPR22(r1) ;\ - l.lwz r23,PT_GPR23(r1) ;\ - l.lwz r24,PT_GPR24(r1) ;\ - l.lwz r25,PT_GPR25(r1) ;\ - l.lwz r26,PT_GPR26(r1) ;\ - l.lwz r27,PT_GPR27(r1) ;\ - l.lwz r28,PT_GPR28(r1) ;\ - l.lwz r29,PT_GPR29(r1) ;\ - l.lwz r30,PT_GPR30(r1) ;\ - l.lwz r31,PT_GPR31(r1) ;\ - l.lwz r1,PT_SP(r1) ;\ - l.rfe - - -#define EXCEPTION_ENTRY(handler) \ - .global handler ;\ -handler: ;\ - /* r1, EPCR, ESR a already saved */ ;\ - l.sw PT_GPR2(r1),r2 ;\ - l.sw PT_GPR3(r1),r3 ;\ - /* r4 already save */ ;\ - l.sw PT_GPR5(r1),r5 ;\ - l.sw PT_GPR6(r1),r6 ;\ - l.sw PT_GPR7(r1),r7 ;\ - l.sw PT_GPR8(r1),r8 ;\ - l.sw PT_GPR9(r1),r9 ;\ - /* r10 already saved */ ;\ - l.sw PT_GPR11(r1),r11 ;\ - /* r12 already saved */ ;\ - l.sw PT_GPR13(r1),r13 ;\ - l.sw PT_GPR14(r1),r14 ;\ - l.sw PT_GPR15(r1),r15 ;\ - l.sw PT_GPR16(r1),r16 ;\ - l.sw PT_GPR17(r1),r17 ;\ - l.sw PT_GPR18(r1),r18 ;\ - l.sw PT_GPR19(r1),r19 ;\ - l.sw PT_GPR20(r1),r20 ;\ - l.sw PT_GPR21(r1),r21 ;\ - l.sw PT_GPR22(r1),r22 ;\ - l.sw PT_GPR23(r1),r23 ;\ - l.sw PT_GPR24(r1),r24 ;\ - l.sw PT_GPR25(r1),r25 ;\ - l.sw PT_GPR26(r1),r26 ;\ - l.sw PT_GPR27(r1),r27 ;\ - l.sw PT_GPR28(r1),r28 ;\ - l.sw PT_GPR29(r1),r29 ;\ - /* r30 already save */ ;\ -/* l.sw PT_GPR30(r1),r30*/ ;\ - l.sw PT_GPR31(r1),r31 ;\ - /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ - l.addi r30,r0,-1 ;\ - l.sw PT_ORIG_GPR11(r1),r30 - -#define UNHANDLED_EXCEPTION(handler,vector) \ - .global handler ;\ -handler: ;\ - /* r1, EPCR, ESR already saved */ ;\ - l.sw PT_GPR2(r1),r2 ;\ - l.sw PT_GPR3(r1),r3 ;\ - l.sw PT_GPR5(r1),r5 ;\ - l.sw PT_GPR6(r1),r6 ;\ - l.sw PT_GPR7(r1),r7 ;\ - l.sw PT_GPR8(r1),r8 ;\ - l.sw PT_GPR9(r1),r9 ;\ - /* r10 already saved */ ;\ - l.sw PT_GPR11(r1),r11 ;\ - /* r12 already saved */ ;\ - l.sw PT_GPR13(r1),r13 ;\ - l.sw PT_GPR14(r1),r14 ;\ - l.sw PT_GPR15(r1),r15 ;\ - l.sw PT_GPR16(r1),r16 ;\ - l.sw PT_GPR17(r1),r17 ;\ - l.sw PT_GPR18(r1),r18 ;\ - l.sw PT_GPR19(r1),r19 ;\ - l.sw PT_GPR20(r1),r20 ;\ - l.sw PT_GPR21(r1),r21 ;\ - l.sw PT_GPR22(r1),r22 ;\ - l.sw PT_GPR23(r1),r23 ;\ - l.sw PT_GPR24(r1),r24 ;\ - l.sw PT_GPR25(r1),r25 ;\ - l.sw PT_GPR26(r1),r26 ;\ - l.sw PT_GPR27(r1),r27 ;\ - l.sw PT_GPR28(r1),r28 ;\ - l.sw PT_GPR29(r1),r29 ;\ - /* r31 already saved */ ;\ - l.sw PT_GPR30(r1),r30 ;\ -/* l.sw PT_GPR31(r1),r31 */ ;\ - /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ - l.addi r30,r0,-1 ;\ - l.sw PT_ORIG_GPR11(r1),r30 ;\ - l.addi r3,r1,0 ;\ - /* r4 is exception EA */ ;\ - l.addi r5,r0,vector ;\ - l.jal unhandled_exception ;\ - l.nop ;\ - l.j _ret_from_exception ;\ - l.nop - -/* - * NOTE: one should never assume that SPR_EPC, SPR_ESR, SPR_EEAR - * contain the same values as when exception we're handling - * occured. in fact they never do. if you need them use - * values saved on stack (for SPR_EPC, SPR_ESR) or content - * of r4 (for SPR_EEAR). for details look at EXCEPTION_HANDLE() - * in 'arch/or32/kernel/head.S' - */ - -/* =====================================================[ exceptions] === */ - -/* ---[ 0x100: RESET exception ]----------------------------------------- */ - -EXCEPTION_ENTRY(_tng_kernel_start) - l.jal _start - l.andi r0,r0,0 - -/* ---[ 0x200: BUS exception ]------------------------------------------- */ - -EXCEPTION_ENTRY(_bus_fault_handler) - /* r4: EA of fault (set by EXCEPTION_HANDLE) */ - l.jal do_bus_fault - l.addi r3,r1,0 /* pt_regs */ - - l.j _ret_from_exception - l.nop - -/* ---[ 0x300: Data Page Fault exception ]------------------------------- */ - -EXCEPTION_ENTRY(_data_page_fault_handler) - /* set up parameters for do_page_fault */ - l.addi r3,r1,0 // pt_regs - /* r4 set be EXCEPTION_HANDLE */ // effective address of fault - l.ori r5,r0,0x300 // exception vector - - /* - * __PHX__: TODO - * - * all this can be written much simpler. look at - * DTLB miss handler in the CONFIG_GUARD_PROTECTED_CORE part - */ -#ifdef CONFIG_OPENRISC_NO_SPR_SR_DSX - l.lwz r6,PT_PC(r3) // address of an offending insn - l.lwz r6,0(r6) // instruction that caused pf - - l.srli r6,r6,26 // check opcode for jump insn - l.sfeqi r6,0 // l.j - l.bf 8f - l.sfeqi r6,1 // l.jal - l.bf 8f - l.sfeqi r6,3 // l.bnf - l.bf 8f - l.sfeqi r6,4 // l.bf - l.bf 8f - l.sfeqi r6,0x11 // l.jr - l.bf 8f - l.sfeqi r6,0x12 // l.jalr - l.bf 8f - - l.nop - - l.j 9f - l.nop -8: - - l.lwz r6,PT_PC(r3) // address of an offending insn - l.addi r6,r6,4 - l.lwz r6,0(r6) // instruction that caused pf - l.srli r6,r6,26 // get opcode -9: - -#else - - l.mfspr r6,r0,SPR_SR // SR -// l.lwz r6,PT_SR(r3) // ESR - l.andi r6,r6,SPR_SR_DSX // check for delay slot exception - l.sfeqi r6,0x1 // exception happened in delay slot - l.bnf 7f - l.lwz r6,PT_PC(r3) // address of an offending insn - - l.addi r6,r6,4 // offending insn is in delay slot -7: - l.lwz r6,0(r6) // instruction that caused pf - l.srli r6,r6,26 // check opcode for write access -#endif - - l.sfgeui r6,0x34 // check opcode for write access - l.bnf 1f - l.sfleui r6,0x37 - l.bnf 1f - l.ori r6,r0,0x1 // write access - l.j 2f - l.nop -1: l.ori r6,r0,0x0 // !write access -2: - - /* call fault.c handler in or32/mm/fault.c */ - l.jal do_page_fault - l.nop - l.j _ret_from_exception - l.nop - -/* ---[ 0x400: Insn Page Fault exception ]------------------------------- */ - -EXCEPTION_ENTRY(_insn_page_fault_handler) - /* set up parameters for do_page_fault */ - l.addi r3,r1,0 // pt_regs - /* r4 set be EXCEPTION_HANDLE */ // effective address of fault - l.ori r5,r0,0x400 // exception vector - l.ori r6,r0,0x0 // !write access - - /* call fault.c handler in or32/mm/fault.c */ - l.jal do_page_fault - l.nop - l.j _ret_from_exception - l.nop - - -/* ---[ 0x500: Timer exception ]----------------------------------------- */ - -EXCEPTION_ENTRY(_timer_handler) - l.jal timer_interrupt - l.addi r3,r1,0 /* pt_regs */ - - l.j _ret_from_intr - l.nop - -/* ---[ 0x600: Aligment exception ]-------------------------------------- */ - -EXCEPTION_ENTRY(_alignment_handler) - /* r4: EA of fault (set by EXCEPTION_HANDLE) */ - l.jal do_unaligned_access - l.addi r3,r1,0 /* pt_regs */ - - l.j _ret_from_exception - l.nop - -#if 0 -EXCEPTION_ENTRY(_aligment_handler) -// l.mfspr r2,r0,SPR_EEAR_BASE /* Load the efective addres */ - l.addi r2,r4,0 -// l.mfspr r5,r0,SPR_EPCR_BASE /* Load the insn address */ - l.lwz r5,PT_PC(r1) - - l.lwz r3,0(r5) /* Load insn */ - l.srli r4,r3,26 /* Shift left to get the insn opcode */ - - l.sfeqi r4,0x00 /* Check if the load/store insn is in delay slot */ - l.bf jmp - l.sfeqi r4,0x01 - l.bf jmp - l.sfeqi r4,0x03 - l.bf jmp - l.sfeqi r4,0x04 - l.bf jmp - l.sfeqi r4,0x11 - l.bf jr - l.sfeqi r4,0x12 - l.bf jr - l.nop - l.j 1f - l.addi r5,r5,4 /* Increment PC to get return insn address */ - -jmp: - l.slli r4,r3,6 /* Get the signed extended jump length */ - l.srai r4,r4,4 - - l.lwz r3,4(r5) /* Load the real load/store insn */ - - l.add r5,r5,r4 /* Calculate jump target address */ - - l.j 1f - l.srli r4,r3,26 /* Shift left to get the insn opcode */ - -jr: - l.slli r4,r3,9 /* Shift to get the reg nb */ - l.andi r4,r4,0x7c - - l.lwz r3,4(r5) /* Load the real load/store insn */ - - l.add r4,r4,r1 /* Load the jump register value from the stack */ - l.lwz r5,0(r4) - - l.srli r4,r3,26 /* Shift left to get the insn opcode */ - - -1: -// l.mtspr r0,r5,SPR_EPCR_BASE - l.sw PT_PC(r1),r5 - - l.sfeqi r4,0x26 - l.bf lhs - l.sfeqi r4,0x25 - l.bf lhz - l.sfeqi r4,0x22 - l.bf lws - l.sfeqi r4,0x21 - l.bf lwz - l.sfeqi r4,0x37 - l.bf sh - l.sfeqi r4,0x35 - l.bf sw - l.nop - -1: l.j 1b /* I don't know what to do */ - l.nop - -lhs: l.lbs r5,0(r2) - l.slli r5,r5,8 - l.lbz r6,1(r2) - l.or r5,r5,r6 - l.srli r4,r3,19 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.j align_end - l.sw 0(r4),r5 - -lhz: l.lbz r5,0(r2) - l.slli r5,r5,8 - l.lbz r6,1(r2) - l.or r5,r5,r6 - l.srli r4,r3,19 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.j align_end - l.sw 0(r4),r5 - -lws: l.lbs r5,0(r2) - l.slli r5,r5,24 - l.lbz r6,1(r2) - l.slli r6,r6,16 - l.or r5,r5,r6 - l.lbz r6,2(r2) - l.slli r6,r6,8 - l.or r5,r5,r6 - l.lbz r6,3(r2) - l.or r5,r5,r6 - l.srli r4,r3,19 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.j align_end - l.sw 0(r4),r5 - -lwz: l.lbz r5,0(r2) - l.slli r5,r5,24 - l.lbz r6,1(r2) - l.slli r6,r6,16 - l.or r5,r5,r6 - l.lbz r6,2(r2) - l.slli r6,r6,8 - l.or r5,r5,r6 - l.lbz r6,3(r2) - l.or r5,r5,r6 - l.srli r4,r3,19 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.j align_end - l.sw 0(r4),r5 - -sh: - l.srli r4,r3,9 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.lwz r5,0(r4) - l.sb 1(r2),r5 - l.srli r5,r5,8 - l.j align_end - l.sb 0(r2),r5 - -sw: - l.srli r4,r3,9 - l.andi r4,r4,0x7c - l.add r4,r4,r1 - l.lwz r5,0(r4) - l.sb 3(r2),r5 - l.srli r5,r5,8 - l.sb 2(r2),r5 - l.srli r5,r5,8 - l.sb 1(r2),r5 - l.srli r5,r5,8 - l.j align_end - l.sb 0(r2),r5 - -align_end: - l.j _ret_from_intr - l.nop -#endif - -/* ---[ 0x700: Illegal insn exception ]---------------------------------- */ - -EXCEPTION_ENTRY(_illegal_instruction_handler) - /* r4: EA of fault (set by EXCEPTION_HANDLE) */ - l.jal do_illegal_instruction - l.addi r3,r1,0 /* pt_regs */ - - l.j _ret_from_exception - l.nop - -/* ---[ 0x800: External interrupt exception ]---------------------------- */ - -EXCEPTION_ENTRY(_external_irq_handler) -#ifdef CONFIG_OPENRISC_ESR_EXCEPTION_BUG_CHECK - l.lwz r4,PT_SR(r1) // were interrupts enabled ? - l.andi r4,r4,SPR_SR_IEE - l.sfeqi r4,0 - l.bnf 1f // ext irq enabled, all ok. - l.nop - - l.addi r1,r1,-0x8 - l.movhi r3,hi(42f) - l.ori r3,r3,lo(42f) - l.sw 0x0(r1),r3 - l.jal printk - l.sw 0x4(r1),r4 - l.addi r1,r1,0x8 - - .section .rodata, "a" -42: - .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r" - .align 4 - .previous - - l.ori r4,r4,SPR_SR_IEE // fix the bug -// l.sw PT_SR(r1),r4 -1: -#endif - l.addi r3,r1,0 - l.movhi r8,hi(do_IRQ) - l.ori r8,r8,lo(do_IRQ) - l.jalr r8 - l.nop - l.j _ret_from_intr - l.nop - -/* ---[ 0x900: DTLB miss exception ]------------------------------------- */ - - -/* ---[ 0xa00: ITLB miss exception ]------------------------------------- */ - - -/* ---[ 0xb00: Range exception ]----------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0xb00,0xb00) - -/* ---[ 0xc00: Syscall exception ]--------------------------------------- */ - -/* - * Syscalls are a special type of exception in that they are - * _explicitly_ invoked by userspace and can therefore be - * held to conform to the same ABI as normal functions with - * respect to whether registers are preserved across the call - * or not. - */ - -/* Upon syscall entry we just save the callee-saved registers - * and not the call-clobbered ones. - */ - -_string_syscall_return: - .string "syscall return %ld \n\r\0" - .align 4 - -ENTRY(_sys_call_handler) - /* syscalls run with interrupts enabled */ - ENABLE_INTERRUPTS(r29) // enable interrupts, r29 is temp - - /* r1, EPCR, ESR a already saved */ - l.sw PT_GPR2(r1),r2 - /* r3-r8 must be saved because syscall restart relies - * on us being able to restart the syscall args... technically - * they should be clobbered, otherwise - */ - l.sw PT_GPR3(r1),r3 - /* r4 already saved */ - /* r4 holds the EEAR address of the fault, load the original r4 */ - l.lwz r4,PT_GPR4(r1) - l.sw PT_GPR5(r1),r5 - l.sw PT_GPR6(r1),r6 - l.sw PT_GPR7(r1),r7 - l.sw PT_GPR8(r1),r8 - l.sw PT_GPR9(r1),r9 - /* r10 already saved */ - l.sw PT_GPR11(r1),r11 - /* orig_gpr11 must be set for syscalls */ - l.sw PT_ORIG_GPR11(r1),r11 - /* r12,r13 already saved */ - - /* r14-r28 (even) aren't touched by the syscall fast path below - * so we don't need to save them. However, the functions that return - * to userspace via a call to switch() DO need to save these because - * switch() effectively clobbers them... saving these registers for - * such functions is handled in their syscall wrappers (see fork, vfork, - * and clone, below). - - /* r30 is the only register we clobber in the fast path */ - /* r30 already saved */ -/* l.sw PT_GPR30(r1),r30 */ - -_syscall_check_trace_enter: - /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ - l.lwz r30,TI_FLAGS(r10) - l.andi r30,r30,_TIF_SYSCALL_TRACE - l.sfne r30,r0 - l.bf _syscall_trace_enter - l.nop - -_syscall_check: - /* Ensure that the syscall number is reasonable */ - l.sfgeui r11,__NR_syscalls - l.bf _syscall_badsys - l.nop - -_syscall_call: - l.movhi r29,hi(sys_call_table) - l.ori r29,r29,lo(sys_call_table) - l.slli r11,r11,2 - l.add r29,r29,r11 - l.lwz r29,0(r29) - - l.jalr r29 - l.nop - -_syscall_return: - /* All syscalls return here... just pay attention to ret_from_fork - * which does it in a round-about way. - */ - l.sw PT_GPR11(r1),r11 // save return value - -#if 0 -_syscall_debug: - l.movhi r3,hi(_string_syscall_return) - l.ori r3,r3,lo(_string_syscall_return) - l.ori r27,r0,1 - l.sw -4(r1),r27 - l.sw -8(r1),r11 - l.addi r1,r1,-8 - l.movhi r27,hi(printk) - l.ori r27,r27,lo(printk) - l.jalr r27 - l.nop - l.addi r1,r1,8 -#endif - -_syscall_check_trace_leave: - /* r30 is a callee-saved register so this should still hold the - * _TIF_SYSCALL_TRACE flag from _syscall_check_trace_enter above... - * _syscall_trace_leave expects syscall result to be in pt_regs->r11. - */ - l.sfne r30,r0 - l.bf _syscall_trace_leave - l.nop - -/* This is where the exception-return code begins... interrupts need to be - * disabled the rest of the way here because we can't afford to miss any - * interrupts that set NEED_RESCHED or SIGNALPENDING... really true? */ - -_syscall_check_work: - /* Here we need to disable interrupts */ - DISABLE_INTERRUPTS(r27,r29) - l.lwz r30,TI_FLAGS(r10) - l.andi r30,r30,_TIF_WORK_MASK - l.sfne r30,r0 - - l.bnf _syscall_resume_userspace - l.nop - - /* Work pending follows a different return path, so we need to - * make sure that all the call-saved registers get into pt_regs - * before branching... - */ - l.sw PT_GPR14(r1),r14 - l.sw PT_GPR16(r1),r16 - l.sw PT_GPR18(r1),r18 - l.sw PT_GPR20(r1),r20 - l.sw PT_GPR22(r1),r22 - l.sw PT_GPR24(r1),r24 - l.sw PT_GPR26(r1),r26 - l.sw PT_GPR28(r1),r28 - - /* _work_pending needs to be called with interrupts disabled */ - l.j _work_pending - l.nop - -_syscall_resume_userspace: -// ENABLE_INTERRUPTS(r29) - - -/* This is the hot path for returning to userspace from a syscall. If there's - * work to be done and the branch to _work_pending was taken above, then the - * return to userspace will be done via the normal exception return path... - * that path restores _all_ registers and will overwrite the "clobbered" - * registers with whatever garbage is in pt_regs -- that's OK because those - * registers are clobbered anyway and because the extra work is insignificant - * in the context of the extra work that _work_pending is doing. - -/* Once again, syscalls are special and only guarantee to preserve the - * same registers as a normal function call */ - -/* The assumption here is that the registers r14-r28 (even) are untouched and - * don't need to be restored... be sure that that's really the case! - */ - -/* This is still too much... we should only be restoring what we actually - * clobbered... we should even be using 'scratch' (odd) regs above so that - * we don't need to restore anything, hardly... - */ - - l.lwz r2,PT_GPR2(r1) - - /* Restore args */ - /* r3-r8 are technically clobbered, but syscall restart needs these - * to be restored... - */ - l.lwz r3,PT_GPR3(r1) - l.lwz r4,PT_GPR4(r1) - l.lwz r5,PT_GPR5(r1) - l.lwz r6,PT_GPR6(r1) - l.lwz r7,PT_GPR7(r1) - l.lwz r8,PT_GPR8(r1) - - l.lwz r9,PT_GPR9(r1) - l.lwz r10,PT_GPR10(r1) - l.lwz r11,PT_GPR11(r1) - - /* r30 is the only register we clobber in the fast path */ - l.lwz r30,PT_GPR30(r1) - - /* Here we use r13-r19 (odd) as scratch regs */ - l.lwz r13,PT_PC(r1) - l.lwz r15,PT_SR(r1) - l.lwz r1,PT_SP(r1) - /* Interrupts need to be disabled for setting EPCR and ESR - * so that another interrupt doesn't come in here and clobber - * them before we can use them for our l.rfe */ - DISABLE_INTERRUPTS(r17,r19) - l.mtspr r0,r13,SPR_EPCR_BASE - l.mtspr r0,r15,SPR_ESR_BASE - l.rfe - -/* End of hot path! - * Keep the below tracing and error handling out of the hot path... -*/ - -_syscall_trace_enter: - /* Here we pass pt_regs to do_syscall_trace_enter. Make sure - * that function is really getting all the info it needs as - * pt_regs isn't a complete set of userspace regs, just the - * ones relevant to the syscall... - * - * Note use of delay slot for setting argument. - */ - l.jal do_syscall_trace_enter - l.addi r3,r1,0 - - /* Restore arguments (not preserved across do_syscall_trace_enter) - * so that we can do the syscall for real and return to the syscall - * hot path. - */ - l.lwz r11,PT_GPR11(r1) - l.lwz r3,PT_GPR3(r1) - l.lwz r4,PT_GPR4(r1) - l.lwz r5,PT_GPR5(r1) - l.lwz r6,PT_GPR6(r1) - l.lwz r7,PT_GPR7(r1) - - l.j _syscall_check - l.lwz r8,PT_GPR8(r1) - -_syscall_trace_leave: - l.jal do_syscall_trace_leave - l.addi r3,r1,0 - - l.j _syscall_check_work - l.nop - -_syscall_badsys: - /* Here we effectively pretend to have executed an imaginary - * syscall that returns -ENOSYS and then return to the regular - * syscall hot path. - * Note that "return value" is set in the delay slot... - */ - l.j _syscall_return - l.addi r11,r0,-ENOSYS - -/******* END SYSCALL HANDLING *******/ - -/* ---[ 0xd00: Trap exception ]------------------------------------------ */ - -UNHANDLED_EXCEPTION(_vector_0xd00,0xd00) - -/* ---[ 0xe00: Trap exception ]------------------------------------------ */ - -EXCEPTION_ENTRY(_trap_handler) - /* r4: EA of fault (set by EXCEPTION_HANDLE) */ - l.jal do_trap - l.addi r3,r1,0 /* pt_regs */ - - l.j _ret_from_exception - l.nop - -/* ---[ 0xf00: Reserved exception ]-------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0xf00,0xf00) - -/* ---[ 0x1000: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1000,0x1000) - -/* ---[ 0x1100: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1100,0x1100) - -/* ---[ 0x1200: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1200,0x1200) - -/* ---[ 0x1300: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1300,0x1300) - -/* ---[ 0x1400: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1400,0x1400) - -/* ---[ 0x1500: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1500,0x1500) - -/* ---[ 0x1600: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1600,0x1600) - -/* ---[ 0x1700: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1700,0x1700) - -/* ---[ 0x1800: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1800,0x1800) - -/* ---[ 0x1900: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1900,0x1900) - -/* ---[ 0x1a00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1a00,0x1a00) - -/* ---[ 0x1b00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1b00,0x1b00) - -/* ---[ 0x1c00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1c00,0x1c00) - -/* ---[ 0x1d00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1d00,0x1d00) - -/* ---[ 0x1e00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1e00,0x1e00) - -/* ---[ 0x1f00: Reserved exception ]------------------------------------- */ - -UNHANDLED_EXCEPTION(_vector_0x1f00,0x1f00) - -/* ========================================================[ return ] === */ - -_work_pending: - /* - * if (current_thread_info->flags & _TIF_NEED_RESCHED) - * schedule(); - */ - l.lwz r5,TI_FLAGS(r10) - l.andi r3,r5,_TIF_NEED_RESCHED - l.sfnei r3,0 - l.bnf _work_notifysig - l.nop - l.jal schedule - l.nop - l.j _resume_userspace - l.nop - -/* Handle pending signals and notify-resume requests. - * do_notify_resume must be passed the latest pushed pt_regs, not - * necessarily the "userspace" ones. Also, pt_regs->syscallno - * must be set so that the syscall restart functionality works. - */ -_work_notifysig: - l.jal do_notify_resume - l.ori r3,r1,0 /* pt_regs */ - -_resume_userspace: - DISABLE_INTERRUPTS(r3,r4) - l.lwz r3,TI_FLAGS(r10) - l.andi r3,r3,_TIF_WORK_MASK - l.sfnei r3,0 - l.bf _work_pending - l.nop - -_restore_all: - RESTORE_ALL - /* This returns to userspace code */ - - -ENTRY(_ret_from_intr) -ENTRY(_ret_from_exception) - l.lwz r4,PT_SR(r1) - l.andi r3,r4,SPR_SR_SM - l.sfeqi r3,0 - l.bnf _restore_all - l.nop - l.j _resume_userspace - l.nop - -ENTRY(ret_from_fork) - l.jal schedule_tail - l.nop - - /* _syscall_returns expect r11 to contain return value */ - l.lwz r11,PT_GPR11(r1) - - /* The syscall fast path return expects call-saved registers - * r12-r28 to be untouched, so we restore them here as they - * will have been effectively clobbered when arriving here - * via the call to switch() - */ - l.lwz r12,PT_GPR12(r1) - l.lwz r14,PT_GPR14(r1) - l.lwz r16,PT_GPR16(r1) - l.lwz r18,PT_GPR18(r1) - l.lwz r20,PT_GPR20(r1) - l.lwz r22,PT_GPR22(r1) - l.lwz r24,PT_GPR24(r1) - l.lwz r26,PT_GPR26(r1) - l.lwz r28,PT_GPR28(r1) - - l.j _syscall_return - l.nop - -/* Since syscalls don't save call-clobbered registers, the args to - * kernel_thread_helper will need to be passed through callee-saved - * registers and copied to the parameter registers when the thread - * begins running. - * - * See arch/openrisc/kernel/process.c: - * The args are passed as follows: - * arg1 (r3) : passed in r20 - * arg2 (r4) : passed in r22 - */ - -ENTRY(_kernel_thread_helper) - l.or r3,r20,r0 - l.or r4,r22,r0 - l.movhi r31,hi(kernel_thread_helper) - l.ori r31,r31,lo(kernel_thread_helper) - l.jr r31 - l.nop - - -/* ========================================================[ switch ] === */ - -/* - * This routine switches between two different tasks. The process - * state of one is saved on its kernel stack. Then the state - * of the other is restored from its kernel stack. The memory - * management hardware is updated to the second process's state. - * Finally, we can return to the second process, via the 'return'. - * - * Note: there are two ways to get to the "going out" portion - * of this code; either by coming in via the entry (_switch) - * or via "fork" which must set up an environment equivalent - * to the "_switch" path. If you change this (or in particular, the - * SAVE_REGS macro), you'll have to change the fork code also. - */ - - -/* _switch MUST never lay on page boundry, cause it runs from - * effective addresses and beeing interrupted by iTLB miss would kill it. - * dTLB miss seams to never accour in the bad place since data accesses - * are from task structures which are always page aligned. - * - * The problem happens in RESTORE_ALL_NO_R11 where we first set the EPCR - * register, then load the previous register values and only at the end call - * the l.rfe instruction. If get TLB miss in beetwen the EPCR register gets - * garbled and we end up calling l.rfe with the wrong EPCR. (same probably - * holds for ESR) - * - * To avoid this problems it is sufficient to align _switch to - * some nice round number smaller than it's size... - */ - -/* ABI rules apply here... we either enter _switch via schedule() or via - * an imaginary call to which we shall return at return_from_fork. Either - * way, we are a function call and only need to preserve the callee-saved - * registers when we return. As such, we don't need to save the registers - * on the stack that we won't be returning as they were... - */ - - .align 0x400 -ENTRY(_switch) - /* We don't store SR as _switch only gets called in a context where - * the SR will be the same going in and coming out... */ - - /* Set up new pt_regs struct for saving task state */ - l.addi r1,r1,-(INT_FRAME_SIZE) - - /* No need to store r1/PT_SP as it goes into KSP below */ - l.sw PT_GPR2(r1),r2 - l.sw PT_GPR9(r1),r9 - /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being - * and expects r12 to be callee-saved... */ - l.sw PT_GPR12(r1),r12 - l.sw PT_GPR14(r1),r14 - l.sw PT_GPR16(r1),r16 - l.sw PT_GPR18(r1),r18 - l.sw PT_GPR20(r1),r20 - l.sw PT_GPR22(r1),r22 - l.sw PT_GPR24(r1),r24 - l.sw PT_GPR26(r1),r26 - l.sw PT_GPR28(r1),r28 - l.sw PT_GPR30(r1),r30 - - l.addi r11,r10,0 /* Save old 'current' to 'last' return value*/ - - /* We use thread_info->ksp for storing the address of the above - * structure so that we can get back to it later... we don't want - * to lose the value of thread_info->ksp, though, so store it as - * pt_regs->sp so that we can easily restore it when we are made - * live again... - */ - - /* Save the old value of thread_info->ksp as pt_regs->sp */ - l.lwz r29,TI_KSP(r10) - l.sw PT_SP(r1),r29 - - /* Swap kernel stack pointers */ - l.sw TI_KSP(r10),r1 /* Save old stack pointer */ - l.or r10,r4,r0 /* Set up new current_thread_info */ - l.lwz r1,TI_KSP(r10) /* Load new stack pointer */ - - /* Restore the old value of thread_info->ksp */ - l.lwz r29,PT_SP(r1) - l.sw TI_KSP(r10),r29 - - /* ...and restore the registers, except r11 because the return value - * has already been set above. - */ - l.lwz r2,PT_GPR2(r1) - l.lwz r9,PT_GPR9(r1) - /* No need to restore r10 */ - /* ...and do not restore r11 */ - - /* This is wrong, r12 shouldn't be here... but GCC is broken for the time being - * and expects r12 to be callee-saved... */ - l.lwz r12,PT_GPR12(r1) - l.lwz r14,PT_GPR14(r1) - l.lwz r16,PT_GPR16(r1) - l.lwz r18,PT_GPR18(r1) - l.lwz r20,PT_GPR20(r1) - l.lwz r22,PT_GPR22(r1) - l.lwz r24,PT_GPR24(r1) - l.lwz r26,PT_GPR26(r1) - l.lwz r28,PT_GPR28(r1) - l.lwz r30,PT_GPR30(r1) - - /* Unwind stack to pre-switch state */ - l.addi r1,r1,(INT_FRAME_SIZE) - - /* Return via the link-register back to where we 'came from', where that can be - * either schedule() or return_from_fork()... */ - l.jr r9 - l.nop - -/* ==================================================================== */ - -/* These all use the delay slot for setting the argument register, so the - * jump is always happening after the l.addi instruction. - * - * These are all just wrappers that don't touch the link-register r9, so the - * return from the "real" syscall function will return back to the syscall - * code that did the l.jal that brought us here. - */ - -/* fork requires that we save all the callee-saved registers because they - * are all effectively clobbered by the call to _switch. Here we store - * all the registers that aren't touched by the syscall fast path and thus - * weren't saved there. - */ - -_fork_save_extra_regs_and_call: - l.sw PT_GPR14(r1),r14 - l.sw PT_GPR16(r1),r16 - l.sw PT_GPR18(r1),r18 - l.sw PT_GPR20(r1),r20 - l.sw PT_GPR22(r1),r22 - l.sw PT_GPR24(r1),r24 - l.sw PT_GPR26(r1),r26 - l.jr r29 - l.sw PT_GPR28(r1),r28 - -ENTRY(sys_clone) - l.movhi r29,hi(_sys_clone) - l.ori r29,r29,lo(_sys_clone) - l.j _fork_save_extra_regs_and_call - l.addi r7,r1,0 - -ENTRY(sys_fork) - l.movhi r29,hi(_sys_fork) - l.ori r29,r29,lo(_sys_fork) - l.j _fork_save_extra_regs_and_call - l.addi r3,r1,0 - -ENTRY(sys_execve) - l.j _sys_execve - l.addi r6,r1,0 - -ENTRY(sys_sigaltstack) - l.j _sys_sigaltstack - l.addi r5,r1,0 - -ENTRY(sys_rt_sigreturn) - l.j _sys_rt_sigreturn - l.addi r3,r1,0 - -/* This is a catch-all syscall for atomic instructions for the OpenRISC 1000. - * The functions takes a variable number of parameters depending on which - * particular flavour of atomic you want... parameter 1 is a flag identifying - * the atomic in question. Currently, this function implements the - * following variants: - * - * XCHG: - * @flag: 1 - * @ptr1: - * @ptr2: - * Atomically exchange the values in pointers 1 and 2. - * - */ - -ENTRY(sys_or1k_atomic) - /* FIXME: This ignores r3 and always does an XCHG */ - DISABLE_INTERRUPTS(r17,r19) - l.lwz r30,0(r4) - l.lwz r28,0(r5) - l.sw 0(r4),r28 - l.sw 0(r5),r30 - ENABLE_INTERRUPTS(r17) - l.jr r9 - l.or r11,r0,r0 - -/* ============================================================[ EOF ]=== */ diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/head.S b/ANDROID_3.4.5/arch/openrisc/kernel/head.S deleted file mode 100644 index 1088b5fc..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/head.S +++ /dev/null @@ -1,1622 +0,0 @@ -/* - * OpenRISC head.S - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/linkage.h> -#include <linux/threads.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/cache.h> -#include <asm/spr_defs.h> -#include <asm/asm-offsets.h> -#include <linux/of_fdt.h> - -#define tophys(rd,rs) \ - l.movhi rd,hi(-KERNELBASE) ;\ - l.add rd,rd,rs - -#define CLEAR_GPR(gpr) \ - l.or gpr,r0,r0 - -#define LOAD_SYMBOL_2_GPR(gpr,symbol) \ - l.movhi gpr,hi(symbol) ;\ - l.ori gpr,gpr,lo(symbol) - - -#define UART_BASE_ADD 0x90000000 - -#define EXCEPTION_SR (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_SM) -#define SYSCALL_SR (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_IEE | SPR_SR_TEE | SPR_SR_SM) - -/* ============================================[ tmp store locations ]=== */ - -/* - * emergency_print temporary stores - */ -#define EMERGENCY_PRINT_STORE_GPR4 l.sw 0x20(r0),r4 -#define EMERGENCY_PRINT_LOAD_GPR4 l.lwz r4,0x20(r0) - -#define EMERGENCY_PRINT_STORE_GPR5 l.sw 0x24(r0),r5 -#define EMERGENCY_PRINT_LOAD_GPR5 l.lwz r5,0x24(r0) - -#define EMERGENCY_PRINT_STORE_GPR6 l.sw 0x28(r0),r6 -#define EMERGENCY_PRINT_LOAD_GPR6 l.lwz r6,0x28(r0) - -#define EMERGENCY_PRINT_STORE_GPR7 l.sw 0x2c(r0),r7 -#define EMERGENCY_PRINT_LOAD_GPR7 l.lwz r7,0x2c(r0) - -#define EMERGENCY_PRINT_STORE_GPR8 l.sw 0x30(r0),r8 -#define EMERGENCY_PRINT_LOAD_GPR8 l.lwz r8,0x30(r0) - -#define EMERGENCY_PRINT_STORE_GPR9 l.sw 0x34(r0),r9 -#define EMERGENCY_PRINT_LOAD_GPR9 l.lwz r9,0x34(r0) - - -/* - * TLB miss handlers temorary stores - */ -#define EXCEPTION_STORE_GPR9 l.sw 0x10(r0),r9 -#define EXCEPTION_LOAD_GPR9 l.lwz r9,0x10(r0) - -#define EXCEPTION_STORE_GPR2 l.sw 0x64(r0),r2 -#define EXCEPTION_LOAD_GPR2 l.lwz r2,0x64(r0) - -#define EXCEPTION_STORE_GPR3 l.sw 0x68(r0),r3 -#define EXCEPTION_LOAD_GPR3 l.lwz r3,0x68(r0) - -#define EXCEPTION_STORE_GPR4 l.sw 0x6c(r0),r4 -#define EXCEPTION_LOAD_GPR4 l.lwz r4,0x6c(r0) - -#define EXCEPTION_STORE_GPR5 l.sw 0x70(r0),r5 -#define EXCEPTION_LOAD_GPR5 l.lwz r5,0x70(r0) - -#define EXCEPTION_STORE_GPR6 l.sw 0x74(r0),r6 -#define EXCEPTION_LOAD_GPR6 l.lwz r6,0x74(r0) - - -/* - * EXCEPTION_HANDLE temporary stores - */ - -#define EXCEPTION_T_STORE_GPR30 l.sw 0x78(r0),r30 -#define EXCEPTION_T_LOAD_GPR30(reg) l.lwz reg,0x78(r0) - -#define EXCEPTION_T_STORE_GPR10 l.sw 0x7c(r0),r10 -#define EXCEPTION_T_LOAD_GPR10(reg) l.lwz reg,0x7c(r0) - -#define EXCEPTION_T_STORE_SP l.sw 0x80(r0),r1 -#define EXCEPTION_T_LOAD_SP(reg) l.lwz reg,0x80(r0) - -/* - * For UNHANLDED_EXCEPTION - */ - -#define EXCEPTION_T_STORE_GPR31 l.sw 0x84(r0),r31 -#define EXCEPTION_T_LOAD_GPR31(reg) l.lwz reg,0x84(r0) - -/* =========================================================[ macros ]=== */ - - -#define GET_CURRENT_PGD(reg,t1) \ - LOAD_SYMBOL_2_GPR(reg,current_pgd) ;\ - tophys (t1,reg) ;\ - l.lwz reg,0(t1) - - -/* - * DSCR: this is a common hook for handling exceptions. it will save - * the needed registers, set up stack and pointer to current - * then jump to the handler while enabling MMU - * - * PRMS: handler - a function to jump to. it has to save the - * remaining registers to kernel stack, call - * appropriate arch-independant exception handler - * and finaly jump to ret_from_except - * - * PREQ: unchanged state from the time exception happened - * - * POST: SAVED the following registers original value - * to the new created exception frame pointed to by r1 - * - * r1 - ksp pointing to the new (exception) frame - * r4 - EEAR exception EA - * r10 - current pointing to current_thread_info struct - * r12 - syscall 0, since we didn't come from syscall - * r13 - temp it actually contains new SR, not needed anymore - * r31 - handler address of the handler we'll jump to - * - * handler has to save remaining registers to the exception - * ksp frame *before* tainting them! - * - * NOTE: this function is not reentrant per se. reentrancy is guaranteed - * by processor disabling all exceptions/interrupts when exception - * accours. - * - * OPTM: no need to make it so wasteful to extract ksp when in user mode - */ - -#define EXCEPTION_HANDLE(handler) \ - EXCEPTION_T_STORE_GPR30 ;\ - l.mfspr r30,r0,SPR_ESR_BASE ;\ - l.andi r30,r30,SPR_SR_SM ;\ - l.sfeqi r30,0 ;\ - EXCEPTION_T_STORE_GPR10 ;\ - l.bnf 2f /* kernel_mode */ ;\ - EXCEPTION_T_STORE_SP /* delay slot */ ;\ -1: /* user_mode: */ ;\ - LOAD_SYMBOL_2_GPR(r1,current_thread_info_set) ;\ - tophys (r30,r1) ;\ - /* r10: current_thread_info */ ;\ - l.lwz r10,0(r30) ;\ - tophys (r30,r10) ;\ - l.lwz r1,(TI_KSP)(r30) ;\ - /* fall through */ ;\ -2: /* kernel_mode: */ ;\ - /* create new stack frame, save only needed gprs */ ;\ - /* r1: KSP, r10: current, r4: EEAR, r31: __pa(KSP) */ ;\ - /* r12: temp, syscall indicator */ ;\ - l.addi r1,r1,-(INT_FRAME_SIZE) ;\ - /* r1 is KSP, r30 is __pa(KSP) */ ;\ - tophys (r30,r1) ;\ - l.sw PT_GPR12(r30),r12 ;\ - l.mfspr r12,r0,SPR_EPCR_BASE ;\ - l.sw PT_PC(r30),r12 ;\ - l.mfspr r12,r0,SPR_ESR_BASE ;\ - l.sw PT_SR(r30),r12 ;\ - /* save r30 */ ;\ - EXCEPTION_T_LOAD_GPR30(r12) ;\ - l.sw PT_GPR30(r30),r12 ;\ - /* save r10 as was prior to exception */ ;\ - EXCEPTION_T_LOAD_GPR10(r12) ;\ - l.sw PT_GPR10(r30),r12 ;\ - /* save PT_SP as was prior to exception */ ;\ - EXCEPTION_T_LOAD_SP(r12) ;\ - l.sw PT_SP(r30),r12 ;\ - /* save exception r4, set r4 = EA */ ;\ - l.sw PT_GPR4(r30),r4 ;\ - l.mfspr r4,r0,SPR_EEAR_BASE ;\ - /* r12 == 1 if we come from syscall */ ;\ - CLEAR_GPR(r12) ;\ - /* ----- turn on MMU ----- */ ;\ - l.ori r30,r0,(EXCEPTION_SR) ;\ - l.mtspr r0,r30,SPR_ESR_BASE ;\ - /* r30: EA address of handler */ ;\ - LOAD_SYMBOL_2_GPR(r30,handler) ;\ - l.mtspr r0,r30,SPR_EPCR_BASE ;\ - l.rfe - -/* - * this doesn't work - * - * - * #ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION - * #define UNHANDLED_EXCEPTION(handler) \ - * l.ori r3,r0,0x1 ;\ - * l.mtspr r0,r3,SPR_SR ;\ - * l.movhi r3,hi(0xf0000100) ;\ - * l.ori r3,r3,lo(0xf0000100) ;\ - * l.jr r3 ;\ - * l.nop 1 - * - * #endif - */ - -/* DSCR: this is the same as EXCEPTION_HANDLE(), we are just - * a bit more carefull (if we have a PT_SP or current pointer - * corruption) and set them up from 'current_set' - * - */ -#define UNHANDLED_EXCEPTION(handler) \ - EXCEPTION_T_STORE_GPR31 ;\ - EXCEPTION_T_STORE_GPR10 ;\ - EXCEPTION_T_STORE_SP ;\ - /* temporary store r3, r9 into r1, r10 */ ;\ - l.addi r1,r3,0x0 ;\ - l.addi r10,r9,0x0 ;\ - /* the string referenced by r3 must be low enough */ ;\ - l.jal _emergency_print ;\ - l.ori r3,r0,lo(_string_unhandled_exception) ;\ - l.mfspr r3,r0,SPR_NPC ;\ - l.jal _emergency_print_nr ;\ - l.andi r3,r3,0x1f00 ;\ - /* the string referenced by r3 must be low enough */ ;\ - l.jal _emergency_print ;\ - l.ori r3,r0,lo(_string_epc_prefix) ;\ - l.jal _emergency_print_nr ;\ - l.mfspr r3,r0,SPR_EPCR_BASE ;\ - l.jal _emergency_print ;\ - l.ori r3,r0,lo(_string_nl) ;\ - /* end of printing */ ;\ - l.addi r3,r1,0x0 ;\ - l.addi r9,r10,0x0 ;\ - /* extract current, ksp from current_set */ ;\ - LOAD_SYMBOL_2_GPR(r1,_unhandled_stack_top) ;\ - LOAD_SYMBOL_2_GPR(r10,init_thread_union) ;\ - /* create new stack frame, save only needed gprs */ ;\ - /* r1: KSP, r10: current, r31: __pa(KSP) */ ;\ - /* r12: temp, syscall indicator, r13 temp */ ;\ - l.addi r1,r1,-(INT_FRAME_SIZE) ;\ - /* r1 is KSP, r31 is __pa(KSP) */ ;\ - tophys (r31,r1) ;\ - l.sw PT_GPR12(r31),r12 ;\ - l.mfspr r12,r0,SPR_EPCR_BASE ;\ - l.sw PT_PC(r31),r12 ;\ - l.mfspr r12,r0,SPR_ESR_BASE ;\ - l.sw PT_SR(r31),r12 ;\ - /* save r31 */ ;\ - EXCEPTION_T_LOAD_GPR31(r12) ;\ - l.sw PT_GPR31(r31),r12 ;\ - /* save r10 as was prior to exception */ ;\ - EXCEPTION_T_LOAD_GPR10(r12) ;\ - l.sw PT_GPR10(r31),r12 ;\ - /* save PT_SP as was prior to exception */ ;\ - EXCEPTION_T_LOAD_SP(r12) ;\ - l.sw PT_SP(r31),r12 ;\ - l.sw PT_GPR13(r31),r13 ;\ - /* --> */ ;\ - /* save exception r4, set r4 = EA */ ;\ - l.sw PT_GPR4(r31),r4 ;\ - l.mfspr r4,r0,SPR_EEAR_BASE ;\ - /* r12 == 1 if we come from syscall */ ;\ - CLEAR_GPR(r12) ;\ - /* ----- play a MMU trick ----- */ ;\ - l.ori r31,r0,(EXCEPTION_SR) ;\ - l.mtspr r0,r31,SPR_ESR_BASE ;\ - /* r31: EA address of handler */ ;\ - LOAD_SYMBOL_2_GPR(r31,handler) ;\ - l.mtspr r0,r31,SPR_EPCR_BASE ;\ - l.rfe - -/* =====================================================[ exceptions] === */ - -/* ---[ 0x100: RESET exception ]----------------------------------------- */ - .org 0x100 - /* Jump to .init code at _start which lives in the .head section - * and will be discarded after boot. - */ - LOAD_SYMBOL_2_GPR(r4, _start) - tophys (r3,r4) /* MMU disabled */ - l.jr r3 - l.nop - -/* ---[ 0x200: BUS exception ]------------------------------------------- */ - .org 0x200 -_dispatch_bus_fault: - EXCEPTION_HANDLE(_bus_fault_handler) - -/* ---[ 0x300: Data Page Fault exception ]------------------------------- */ - .org 0x300 -_dispatch_do_dpage_fault: -// totaly disable timer interrupt -// l.mtspr r0,r0,SPR_TTMR -// DEBUG_TLB_PROBE(0x300) -// EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x300) - EXCEPTION_HANDLE(_data_page_fault_handler) - -/* ---[ 0x400: Insn Page Fault exception ]------------------------------- */ - .org 0x400 -_dispatch_do_ipage_fault: -// totaly disable timer interrupt -// l.mtspr r0,r0,SPR_TTMR -// DEBUG_TLB_PROBE(0x400) -// EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x400) - EXCEPTION_HANDLE(_insn_page_fault_handler) - -/* ---[ 0x500: Timer exception ]----------------------------------------- */ - .org 0x500 - EXCEPTION_HANDLE(_timer_handler) - -/* ---[ 0x600: Aligment exception ]-------------------------------------- */ - .org 0x600 - EXCEPTION_HANDLE(_alignment_handler) - -/* ---[ 0x700: Illegal insn exception ]---------------------------------- */ - .org 0x700 - EXCEPTION_HANDLE(_illegal_instruction_handler) - -/* ---[ 0x800: External interrupt exception ]---------------------------- */ - .org 0x800 - EXCEPTION_HANDLE(_external_irq_handler) - -/* ---[ 0x900: DTLB miss exception ]------------------------------------- */ - .org 0x900 - l.j boot_dtlb_miss_handler - l.nop - -/* ---[ 0xa00: ITLB miss exception ]------------------------------------- */ - .org 0xa00 - l.j boot_itlb_miss_handler - l.nop - -/* ---[ 0xb00: Range exception ]----------------------------------------- */ - .org 0xb00 - UNHANDLED_EXCEPTION(_vector_0xb00) - -/* ---[ 0xc00: Syscall exception ]--------------------------------------- */ - .org 0xc00 - EXCEPTION_HANDLE(_sys_call_handler) - -/* ---[ 0xd00: Trap exception ]------------------------------------------ */ - .org 0xd00 - UNHANDLED_EXCEPTION(_vector_0xd00) - -/* ---[ 0xe00: Trap exception ]------------------------------------------ */ - .org 0xe00 -// UNHANDLED_EXCEPTION(_vector_0xe00) - EXCEPTION_HANDLE(_trap_handler) - -/* ---[ 0xf00: Reserved exception ]-------------------------------------- */ - .org 0xf00 - UNHANDLED_EXCEPTION(_vector_0xf00) - -/* ---[ 0x1000: Reserved exception ]------------------------------------- */ - .org 0x1000 - UNHANDLED_EXCEPTION(_vector_0x1000) - -/* ---[ 0x1100: Reserved exception ]------------------------------------- */ - .org 0x1100 - UNHANDLED_EXCEPTION(_vector_0x1100) - -/* ---[ 0x1200: Reserved exception ]------------------------------------- */ - .org 0x1200 - UNHANDLED_EXCEPTION(_vector_0x1200) - -/* ---[ 0x1300: Reserved exception ]------------------------------------- */ - .org 0x1300 - UNHANDLED_EXCEPTION(_vector_0x1300) - -/* ---[ 0x1400: Reserved exception ]------------------------------------- */ - .org 0x1400 - UNHANDLED_EXCEPTION(_vector_0x1400) - -/* ---[ 0x1500: Reserved exception ]------------------------------------- */ - .org 0x1500 - UNHANDLED_EXCEPTION(_vector_0x1500) - -/* ---[ 0x1600: Reserved exception ]------------------------------------- */ - .org 0x1600 - UNHANDLED_EXCEPTION(_vector_0x1600) - -/* ---[ 0x1700: Reserved exception ]------------------------------------- */ - .org 0x1700 - UNHANDLED_EXCEPTION(_vector_0x1700) - -/* ---[ 0x1800: Reserved exception ]------------------------------------- */ - .org 0x1800 - UNHANDLED_EXCEPTION(_vector_0x1800) - -/* ---[ 0x1900: Reserved exception ]------------------------------------- */ - .org 0x1900 - UNHANDLED_EXCEPTION(_vector_0x1900) - -/* ---[ 0x1a00: Reserved exception ]------------------------------------- */ - .org 0x1a00 - UNHANDLED_EXCEPTION(_vector_0x1a00) - -/* ---[ 0x1b00: Reserved exception ]------------------------------------- */ - .org 0x1b00 - UNHANDLED_EXCEPTION(_vector_0x1b00) - -/* ---[ 0x1c00: Reserved exception ]------------------------------------- */ - .org 0x1c00 - UNHANDLED_EXCEPTION(_vector_0x1c00) - -/* ---[ 0x1d00: Reserved exception ]------------------------------------- */ - .org 0x1d00 - UNHANDLED_EXCEPTION(_vector_0x1d00) - -/* ---[ 0x1e00: Reserved exception ]------------------------------------- */ - .org 0x1e00 - UNHANDLED_EXCEPTION(_vector_0x1e00) - -/* ---[ 0x1f00: Reserved exception ]------------------------------------- */ - .org 0x1f00 - UNHANDLED_EXCEPTION(_vector_0x1f00) - - .org 0x2000 -/* ===================================================[ kernel start ]=== */ - -/* .text*/ - -/* This early stuff belongs in HEAD, but some of the functions below definitely - * don't... */ - - __HEAD - .global _start -_start: - /* save kernel parameters */ - l.or r25,r0,r3 /* pointer to fdt */ - - /* - * ensure a deterministic start - */ - - l.ori r3,r0,0x1 - l.mtspr r0,r3,SPR_SR - - CLEAR_GPR(r1) - CLEAR_GPR(r2) - CLEAR_GPR(r3) - CLEAR_GPR(r4) - CLEAR_GPR(r5) - CLEAR_GPR(r6) - CLEAR_GPR(r7) - CLEAR_GPR(r8) - CLEAR_GPR(r9) - CLEAR_GPR(r10) - CLEAR_GPR(r11) - CLEAR_GPR(r12) - CLEAR_GPR(r13) - CLEAR_GPR(r14) - CLEAR_GPR(r15) - CLEAR_GPR(r16) - CLEAR_GPR(r17) - CLEAR_GPR(r18) - CLEAR_GPR(r19) - CLEAR_GPR(r20) - CLEAR_GPR(r21) - CLEAR_GPR(r22) - CLEAR_GPR(r23) - CLEAR_GPR(r24) - CLEAR_GPR(r26) - CLEAR_GPR(r27) - CLEAR_GPR(r28) - CLEAR_GPR(r29) - CLEAR_GPR(r30) - CLEAR_GPR(r31) - - /* - * set up initial ksp and current - */ - LOAD_SYMBOL_2_GPR(r1,init_thread_union+0x2000) // setup kernel stack - LOAD_SYMBOL_2_GPR(r10,init_thread_union) // setup current - tophys (r31,r10) - l.sw TI_KSP(r31), r1 - - l.ori r4,r0,0x0 - - - /* - * .data contains initialized data, - * .bss contains uninitialized data - clear it up - */ -clear_bss: - LOAD_SYMBOL_2_GPR(r24, __bss_start) - LOAD_SYMBOL_2_GPR(r26, _end) - tophys(r28,r24) - tophys(r30,r26) - CLEAR_GPR(r24) - CLEAR_GPR(r26) -1: - l.sw (0)(r28),r0 - l.sfltu r28,r30 - l.bf 1b - l.addi r28,r28,4 - -enable_ic: - l.jal _ic_enable - l.nop - -enable_dc: - l.jal _dc_enable - l.nop - -flush_tlb: - /* - * I N V A L I D A T E T L B e n t r i e s - */ - LOAD_SYMBOL_2_GPR(r5,SPR_DTLBMR_BASE(0)) - LOAD_SYMBOL_2_GPR(r6,SPR_ITLBMR_BASE(0)) - l.addi r7,r0,128 /* Maximum number of sets */ -1: - l.mtspr r5,r0,0x0 - l.mtspr r6,r0,0x0 - - l.addi r5,r5,1 - l.addi r6,r6,1 - l.sfeq r7,r0 - l.bnf 1b - l.addi r7,r7,-1 - - -/* The MMU needs to be enabled before or32_early_setup is called */ - -enable_mmu: - /* - * enable dmmu & immu - * SR[5] = 0, SR[6] = 0, 6th and 7th bit of SR set to 0 - */ - l.mfspr r30,r0,SPR_SR - l.movhi r28,hi(SPR_SR_DME | SPR_SR_IME) - l.ori r28,r28,lo(SPR_SR_DME | SPR_SR_IME) - l.or r30,r30,r28 - l.mtspr r0,r30,SPR_SR - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - - // reset the simulation counters - l.nop 5 - - /* check fdt header magic word */ - l.lwz r3,0(r25) /* load magic from fdt into r3 */ - l.movhi r4,hi(OF_DT_HEADER) - l.ori r4,r4,lo(OF_DT_HEADER) - l.sfeq r3,r4 - l.bf _fdt_found - l.nop - /* magic number mismatch, set fdt pointer to null */ - l.or r25,r0,r0 -_fdt_found: - /* pass fdt pointer to or32_early_setup in r3 */ - l.or r3,r0,r25 - LOAD_SYMBOL_2_GPR(r24, or32_early_setup) - l.jalr r24 - l.nop - -clear_regs: - /* - * clear all GPRS to increase determinism - */ - CLEAR_GPR(r2) - CLEAR_GPR(r3) - CLEAR_GPR(r4) - CLEAR_GPR(r5) - CLEAR_GPR(r6) - CLEAR_GPR(r7) - CLEAR_GPR(r8) - CLEAR_GPR(r9) - CLEAR_GPR(r11) - CLEAR_GPR(r12) - CLEAR_GPR(r13) - CLEAR_GPR(r14) - CLEAR_GPR(r15) - CLEAR_GPR(r16) - CLEAR_GPR(r17) - CLEAR_GPR(r18) - CLEAR_GPR(r19) - CLEAR_GPR(r20) - CLEAR_GPR(r21) - CLEAR_GPR(r22) - CLEAR_GPR(r23) - CLEAR_GPR(r24) - CLEAR_GPR(r25) - CLEAR_GPR(r26) - CLEAR_GPR(r27) - CLEAR_GPR(r28) - CLEAR_GPR(r29) - CLEAR_GPR(r30) - CLEAR_GPR(r31) - -jump_start_kernel: - /* - * jump to kernel entry (start_kernel) - */ - LOAD_SYMBOL_2_GPR(r30, start_kernel) - l.jr r30 - l.nop - -/* ========================================[ cache ]=== */ - - /* aligment here so we don't change memory offsets with - * memory controler defined - */ - .align 0x2000 - -_ic_enable: - /* Check if IC present and skip enabling otherwise */ - l.mfspr r24,r0,SPR_UPR - l.andi r26,r24,SPR_UPR_ICP - l.sfeq r26,r0 - l.bf 9f - l.nop - - /* Disable IC */ - l.mfspr r6,r0,SPR_SR - l.addi r5,r0,-1 - l.xori r5,r5,SPR_SR_ICE - l.and r5,r6,r5 - l.mtspr r0,r5,SPR_SR - - /* Establish cache block size - If BS=0, 16; - If BS=1, 32; - r14 contain block size - */ - l.mfspr r24,r0,SPR_ICCFGR - l.andi r26,r24,SPR_ICCFGR_CBS - l.srli r28,r26,7 - l.ori r30,r0,16 - l.sll r14,r30,r28 - - /* Establish number of cache sets - r16 contains number of cache sets - r28 contains log(# of cache sets) - */ - l.andi r26,r24,SPR_ICCFGR_NCS - l.srli r28,r26,3 - l.ori r30,r0,1 - l.sll r16,r30,r28 - - /* Invalidate IC */ - l.addi r6,r0,0 - l.sll r5,r14,r28 -// l.mul r5,r14,r16 -// l.trap 1 -// l.addi r5,r0,IC_SIZE -1: - l.mtspr r0,r6,SPR_ICBIR - l.sfne r6,r5 - l.bf 1b - l.add r6,r6,r14 - // l.addi r6,r6,IC_LINE - - /* Enable IC */ - l.mfspr r6,r0,SPR_SR - l.ori r6,r6,SPR_SR_ICE - l.mtspr r0,r6,SPR_SR - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop - l.nop -9: - l.jr r9 - l.nop - -_dc_enable: - /* Check if DC present and skip enabling otherwise */ - l.mfspr r24,r0,SPR_UPR - l.andi r26,r24,SPR_UPR_DCP - l.sfeq r26,r0 - l.bf 9f - l.nop - - /* Disable DC */ - l.mfspr r6,r0,SPR_SR - l.addi r5,r0,-1 - l.xori r5,r5,SPR_SR_DCE - l.and r5,r6,r5 - l.mtspr r0,r5,SPR_SR - - /* Establish cache block size - If BS=0, 16; - If BS=1, 32; - r14 contain block size - */ - l.mfspr r24,r0,SPR_DCCFGR - l.andi r26,r24,SPR_DCCFGR_CBS - l.srli r28,r26,7 - l.ori r30,r0,16 - l.sll r14,r30,r28 - - /* Establish number of cache sets - r16 contains number of cache sets - r28 contains log(# of cache sets) - */ - l.andi r26,r24,SPR_DCCFGR_NCS - l.srli r28,r26,3 - l.ori r30,r0,1 - l.sll r16,r30,r28 - - /* Invalidate DC */ - l.addi r6,r0,0 - l.sll r5,r14,r28 -1: - l.mtspr r0,r6,SPR_DCBIR - l.sfne r6,r5 - l.bf 1b - l.add r6,r6,r14 - - /* Enable DC */ - l.mfspr r6,r0,SPR_SR - l.ori r6,r6,SPR_SR_DCE - l.mtspr r0,r6,SPR_SR -9: - l.jr r9 - l.nop - -/* ===============================================[ page table masks ]=== */ - -/* bit 4 is used in hardware as write back cache bit. we never use this bit - * explicitly, so we can reuse it as _PAGE_FILE bit and mask it out when - * writing into hardware pte's - */ - -#define DTLB_UP_CONVERT_MASK 0x3fa -#define ITLB_UP_CONVERT_MASK 0x3a - -/* for SMP we'd have (this is a bit subtle, CC must be always set - * for SMP, but since we have _PAGE_PRESENT bit always defined - * we can just modify the mask) - */ -#define DTLB_SMP_CONVERT_MASK 0x3fb -#define ITLB_SMP_CONVERT_MASK 0x3b - -/* ---[ boot dtlb miss handler ]----------------------------------------- */ - -boot_dtlb_miss_handler: - -/* mask for DTLB_MR register: - (0) sets V (valid) bit, - * - (31-12) sets bits belonging to VPN (31-12) - */ -#define DTLB_MR_MASK 0xfffff001 - -/* mask for DTLB_TR register: - (2) sets CI (cache inhibit) bit, - * - (4) sets A (access) bit, - * - (5) sets D (dirty) bit, - * - (8) sets SRE (superuser read) bit - * - (9) sets SWE (superuser write) bit - * - (31-12) sets bits belonging to VPN (31-12) - */ -#define DTLB_TR_MASK 0xfffff332 - -/* These are for masking out the VPN/PPN value from the MR/TR registers... - * it's not the same as the PFN */ -#define VPN_MASK 0xfffff000 -#define PPN_MASK 0xfffff000 - - - EXCEPTION_STORE_GPR6 - -#if 0 - l.mfspr r6,r0,SPR_ESR_BASE // - l.andi r6,r6,SPR_SR_SM // are we in kernel mode ? - l.sfeqi r6,0 // r6 == 0x1 --> SM - l.bf exit_with_no_dtranslation // - l.nop -#endif - - /* this could be optimized by moving storing of - * non r6 registers here, and jumping r6 restore - * if not in supervisor mode - */ - - EXCEPTION_STORE_GPR2 - EXCEPTION_STORE_GPR3 - EXCEPTION_STORE_GPR4 - EXCEPTION_STORE_GPR5 - - l.mfspr r4,r0,SPR_EEAR_BASE // get the offending EA - -immediate_translation: - CLEAR_GPR(r6) - - l.srli r3,r4,0xd // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb) - - l.mfspr r6, r0, SPR_DMMUCFGR - l.andi r6, r6, SPR_DMMUCFGR_NTS - l.srli r6, r6, SPR_DMMUCFGR_NTS_OFF - l.ori r5, r0, 0x1 - l.sll r5, r5, r6 // r5 = number DMMU sets - l.addi r6, r5, -1 // r6 = nsets mask - l.and r2, r3, r6 // r2 <- r3 % NSETS_MASK - - l.or r6,r6,r4 // r6 <- r4 - l.ori r6,r6,~(VPN_MASK) // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff - l.movhi r5,hi(DTLB_MR_MASK) // r5 <- ffff:0000.x000 - l.ori r5,r5,lo(DTLB_MR_MASK) // r5 <- ffff:1111.x001 - apply DTLB_MR_MASK - l.and r5,r5,r6 // r5 <- VPN :VPN .x001 - we have DTLBMR entry - l.mtspr r2,r5,SPR_DTLBMR_BASE(0) // set DTLBMR - - /* set up DTLB with no translation for EA <= 0xbfffffff */ - LOAD_SYMBOL_2_GPR(r6,0xbfffffff) - l.sfgeu r6,r4 // flag if r6 >= r4 (if 0xbfffffff >= EA) - l.bf 1f // goto out - l.and r3,r4,r4 // delay slot :: 24 <- r4 (if flag==1) - - tophys(r3,r4) // r3 <- PA -1: - l.ori r3,r3,~(PPN_MASK) // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff - l.movhi r5,hi(DTLB_TR_MASK) // r5 <- ffff:0000.x000 - l.ori r5,r5,lo(DTLB_TR_MASK) // r5 <- ffff:1111.x330 - apply DTLB_MR_MASK - l.and r5,r5,r3 // r5 <- PPN :PPN .x330 - we have DTLBTR entry - l.mtspr r2,r5,SPR_DTLBTR_BASE(0) // set DTLBTR - - EXCEPTION_LOAD_GPR6 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR2 - - l.rfe // SR <- ESR, PC <- EPC - -exit_with_no_dtranslation: - /* EA out of memory or not in supervisor mode */ - EXCEPTION_LOAD_GPR6 - EXCEPTION_LOAD_GPR4 - l.j _dispatch_bus_fault - -/* ---[ boot itlb miss handler ]----------------------------------------- */ - -boot_itlb_miss_handler: - -/* mask for ITLB_MR register: - sets V (valid) bit, - * - sets bits belonging to VPN (15-12) - */ -#define ITLB_MR_MASK 0xfffff001 - -/* mask for ITLB_TR register: - sets A (access) bit, - * - sets SXE (superuser execute) bit - * - sets bits belonging to VPN (15-12) - */ -#define ITLB_TR_MASK 0xfffff050 - -/* -#define VPN_MASK 0xffffe000 -#define PPN_MASK 0xffffe000 -*/ - - - - EXCEPTION_STORE_GPR2 - EXCEPTION_STORE_GPR3 - EXCEPTION_STORE_GPR4 - EXCEPTION_STORE_GPR5 - EXCEPTION_STORE_GPR6 - -#if 0 - l.mfspr r6,r0,SPR_ESR_BASE // - l.andi r6,r6,SPR_SR_SM // are we in kernel mode ? - l.sfeqi r6,0 // r6 == 0x1 --> SM - l.bf exit_with_no_itranslation - l.nop -#endif - - - l.mfspr r4,r0,SPR_EEAR_BASE // get the offending EA - -earlyearly: - CLEAR_GPR(r6) - - l.srli r3,r4,0xd // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb) - - l.mfspr r6, r0, SPR_IMMUCFGR - l.andi r6, r6, SPR_IMMUCFGR_NTS - l.srli r6, r6, SPR_IMMUCFGR_NTS_OFF - l.ori r5, r0, 0x1 - l.sll r5, r5, r6 // r5 = number IMMU sets from IMMUCFGR - l.addi r6, r5, -1 // r6 = nsets mask - l.and r2, r3, r6 // r2 <- r3 % NSETS_MASK - - l.or r6,r6,r4 // r6 <- r4 - l.ori r6,r6,~(VPN_MASK) // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff - l.movhi r5,hi(ITLB_MR_MASK) // r5 <- ffff:0000.x000 - l.ori r5,r5,lo(ITLB_MR_MASK) // r5 <- ffff:1111.x001 - apply ITLB_MR_MASK - l.and r5,r5,r6 // r5 <- VPN :VPN .x001 - we have ITLBMR entry - l.mtspr r2,r5,SPR_ITLBMR_BASE(0) // set ITLBMR - - /* - * set up ITLB with no translation for EA <= 0x0fffffff - * - * we need this for head.S mapping (EA = PA). if we move all functions - * which run with mmu enabled into entry.S, we might be able to eliminate this. - * - */ - LOAD_SYMBOL_2_GPR(r6,0x0fffffff) - l.sfgeu r6,r4 // flag if r6 >= r4 (if 0xb0ffffff >= EA) - l.bf 1f // goto out - l.and r3,r4,r4 // delay slot :: 24 <- r4 (if flag==1) - - tophys(r3,r4) // r3 <- PA -1: - l.ori r3,r3,~(PPN_MASK) // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff - l.movhi r5,hi(ITLB_TR_MASK) // r5 <- ffff:0000.x000 - l.ori r5,r5,lo(ITLB_TR_MASK) // r5 <- ffff:1111.x050 - apply ITLB_MR_MASK - l.and r5,r5,r3 // r5 <- PPN :PPN .x050 - we have ITLBTR entry - l.mtspr r2,r5,SPR_ITLBTR_BASE(0) // set ITLBTR - - EXCEPTION_LOAD_GPR6 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR2 - - l.rfe // SR <- ESR, PC <- EPC - -exit_with_no_itranslation: - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR6 - l.j _dispatch_bus_fault - l.nop - -/* ====================================================================== */ -/* - * Stuff below here shouldn't go into .head section... maybe this stuff - * can be moved to entry.S ??? - */ - -/* ==============================================[ DTLB miss handler ]=== */ - -/* - * Comments: - * Exception handlers are entered with MMU off so the following handler - * needs to use physical addressing - * - */ - - .text -ENTRY(dtlb_miss_handler) - EXCEPTION_STORE_GPR2 - EXCEPTION_STORE_GPR3 - EXCEPTION_STORE_GPR4 - EXCEPTION_STORE_GPR5 - EXCEPTION_STORE_GPR6 - /* - * get EA of the miss - */ - l.mfspr r2,r0,SPR_EEAR_BASE - /* - * pmd = (pmd_t *)(current_pgd + pgd_index(daddr)); - */ - GET_CURRENT_PGD(r3,r5) // r3 is current_pgd, r5 is temp - l.srli r4,r2,0x18 // >> PAGE_SHIFT + (PAGE_SHIFT - 2) - l.slli r4,r4,0x2 // to get address << 2 - l.add r5,r4,r3 // r4 is pgd_index(daddr) - /* - * if (pmd_none(*pmd)) - * goto pmd_none: - */ - tophys (r4,r5) - l.lwz r3,0x0(r4) // get *pmd value - l.sfne r3,r0 - l.bnf d_pmd_none - l.andi r3,r3,~PAGE_MASK //0x1fff // ~PAGE_MASK - /* - * if (pmd_bad(*pmd)) - * pmd_clear(pmd) - * goto pmd_bad: - */ -// l.sfeq r3,r0 // check *pmd value -// l.bf d_pmd_good - l.addi r3,r0,0xffffe000 // PAGE_MASK -// l.j d_pmd_bad -// l.sw 0x0(r4),r0 // clear pmd -d_pmd_good: - /* - * pte = *pte_offset(pmd, daddr); - */ - l.lwz r4,0x0(r4) // get **pmd value - l.and r4,r4,r3 // & PAGE_MASK - l.srli r5,r2,0xd // >> PAGE_SHIFT, r2 == EEAR - l.andi r3,r5,0x7ff // (1UL << PAGE_SHIFT - 2) - 1 - l.slli r3,r3,0x2 // to get address << 2 - l.add r3,r3,r4 - l.lwz r2,0x0(r3) // this is pte at last - /* - * if (!pte_present(pte)) - */ - l.andi r4,r2,0x1 - l.sfne r4,r0 // is pte present - l.bnf d_pte_not_present - l.addi r3,r0,0xffffe3fa // PAGE_MASK | DTLB_UP_CONVERT_MASK - /* - * fill DTLB TR register - */ - l.and r4,r2,r3 // apply the mask - // Determine number of DMMU sets - l.mfspr r6, r0, SPR_DMMUCFGR - l.andi r6, r6, SPR_DMMUCFGR_NTS - l.srli r6, r6, SPR_DMMUCFGR_NTS_OFF - l.ori r3, r0, 0x1 - l.sll r3, r3, r6 // r3 = number DMMU sets DMMUCFGR - l.addi r6, r3, -1 // r6 = nsets mask - l.and r5, r5, r6 // calc offset: & (NUM_TLB_ENTRIES-1) - //NUM_TLB_ENTRIES - l.mtspr r5,r4,SPR_DTLBTR_BASE(0) - /* - * fill DTLB MR register - */ - l.mfspr r2,r0,SPR_EEAR_BASE - l.addi r3,r0,0xffffe000 // PAGE_MASK - l.and r4,r2,r3 // apply PAGE_MASK to EA (__PHX__ do we really need this?) - l.ori r4,r4,0x1 // set hardware valid bit: DTBL_MR entry - l.mtspr r5,r4,SPR_DTLBMR_BASE(0) - - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.rfe -d_pmd_bad: - l.nop 1 - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.rfe -d_pmd_none: -d_pte_not_present: - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.j _dispatch_do_dpage_fault - l.nop - -/* ==============================================[ ITLB miss handler ]=== */ -ENTRY(itlb_miss_handler) - EXCEPTION_STORE_GPR2 - EXCEPTION_STORE_GPR3 - EXCEPTION_STORE_GPR4 - EXCEPTION_STORE_GPR5 - EXCEPTION_STORE_GPR6 - /* - * get EA of the miss - */ - l.mfspr r2,r0,SPR_EEAR_BASE - - /* - * pmd = (pmd_t *)(current_pgd + pgd_index(daddr)); - * - */ - GET_CURRENT_PGD(r3,r5) // r3 is current_pgd, r5 is temp - l.srli r4,r2,0x18 // >> PAGE_SHIFT + (PAGE_SHIFT - 2) - l.slli r4,r4,0x2 // to get address << 2 - l.add r5,r4,r3 // r4 is pgd_index(daddr) - /* - * if (pmd_none(*pmd)) - * goto pmd_none: - */ - tophys (r4,r5) - l.lwz r3,0x0(r4) // get *pmd value - l.sfne r3,r0 - l.bnf i_pmd_none - l.andi r3,r3,0x1fff // ~PAGE_MASK - /* - * if (pmd_bad(*pmd)) - * pmd_clear(pmd) - * goto pmd_bad: - */ - -// l.sfeq r3,r0 // check *pmd value -// l.bf i_pmd_good - l.addi r3,r0,0xffffe000 // PAGE_MASK -// l.j i_pmd_bad -// l.sw 0x0(r4),r0 // clear pmd - -i_pmd_good: - /* - * pte = *pte_offset(pmd, iaddr); - * - */ - l.lwz r4,0x0(r4) // get **pmd value - l.and r4,r4,r3 // & PAGE_MASK - l.srli r5,r2,0xd // >> PAGE_SHIFT, r2 == EEAR - l.andi r3,r5,0x7ff // (1UL << PAGE_SHIFT - 2) - 1 - l.slli r3,r3,0x2 // to get address << 2 - l.add r3,r3,r4 - l.lwz r2,0x0(r3) // this is pte at last - /* - * if (!pte_present(pte)) - * - */ - l.andi r4,r2,0x1 - l.sfne r4,r0 // is pte present - l.bnf i_pte_not_present - l.addi r3,r0,0xffffe03a // PAGE_MASK | ITLB_UP_CONVERT_MASK - /* - * fill ITLB TR register - */ - l.and r4,r2,r3 // apply the mask - l.andi r3,r2,0x7c0 // _PAGE_EXEC | _PAGE_SRE | _PAGE_SWE | _PAGE_URE | _PAGE_UWE -// l.andi r3,r2,0x400 // _PAGE_EXEC - l.sfeq r3,r0 - l.bf itlb_tr_fill //_workaround - // Determine number of IMMU sets - l.mfspr r6, r0, SPR_IMMUCFGR - l.andi r6, r6, SPR_IMMUCFGR_NTS - l.srli r6, r6, SPR_IMMUCFGR_NTS_OFF - l.ori r3, r0, 0x1 - l.sll r3, r3, r6 // r3 = number IMMU sets IMMUCFGR - l.addi r6, r3, -1 // r6 = nsets mask - l.and r5, r5, r6 // calc offset: & (NUM_TLB_ENTRIES-1) - -/* - * __PHX__ :: fixme - * we should not just blindly set executable flags, - * but it does help with ping. the clean way would be to find out - * (and fix it) why stack doesn't have execution permissions - */ - -itlb_tr_fill_workaround: - l.ori r4,r4,0xc0 // | (SPR_ITLBTR_UXE | ITLBTR_SXE) -itlb_tr_fill: - l.mtspr r5,r4,SPR_ITLBTR_BASE(0) - /* - * fill DTLB MR register - */ - l.mfspr r2,r0,SPR_EEAR_BASE - l.addi r3,r0,0xffffe000 // PAGE_MASK - l.and r4,r2,r3 // apply PAGE_MASK to EA (__PHX__ do we really need this?) - l.ori r4,r4,0x1 // set hardware valid bit: DTBL_MR entry - l.mtspr r5,r4,SPR_ITLBMR_BASE(0) - - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.rfe - -i_pmd_bad: - l.nop 1 - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.rfe -i_pmd_none: -i_pte_not_present: - EXCEPTION_LOAD_GPR2 - EXCEPTION_LOAD_GPR3 - EXCEPTION_LOAD_GPR4 - EXCEPTION_LOAD_GPR5 - EXCEPTION_LOAD_GPR6 - l.j _dispatch_do_ipage_fault - l.nop - -/* ==============================================[ boot tlb handlers ]=== */ - - -/* =================================================[ debugging aids ]=== */ - - .align 64 -_immu_trampoline: - .space 64 -_immu_trampoline_top: - -#define TRAMP_SLOT_0 (0x0) -#define TRAMP_SLOT_1 (0x4) -#define TRAMP_SLOT_2 (0x8) -#define TRAMP_SLOT_3 (0xc) -#define TRAMP_SLOT_4 (0x10) -#define TRAMP_SLOT_5 (0x14) -#define TRAMP_FRAME_SIZE (0x18) - -ENTRY(_immu_trampoline_workaround) - // r2 EEA - // r6 is physical EEA - tophys(r6,r2) - - LOAD_SYMBOL_2_GPR(r5,_immu_trampoline) - tophys (r3,r5) // r3 is trampoline (physical) - - LOAD_SYMBOL_2_GPR(r4,0x15000000) - l.sw TRAMP_SLOT_0(r3),r4 - l.sw TRAMP_SLOT_1(r3),r4 - l.sw TRAMP_SLOT_4(r3),r4 - l.sw TRAMP_SLOT_5(r3),r4 - - // EPC = EEA - 0x4 - l.lwz r4,0x0(r6) // load op @ EEA + 0x0 (fc address) - l.sw TRAMP_SLOT_3(r3),r4 // store it to _immu_trampoline_data - l.lwz r4,-0x4(r6) // load op @ EEA - 0x4 (f8 address) - l.sw TRAMP_SLOT_2(r3),r4 // store it to _immu_trampoline_data - - l.srli r5,r4,26 // check opcode for write access - l.sfeqi r5,0 // l.j - l.bf 0f - l.sfeqi r5,0x11 // l.jr - l.bf 1f - l.sfeqi r5,1 // l.jal - l.bf 2f - l.sfeqi r5,0x12 // l.jalr - l.bf 3f - l.sfeqi r5,3 // l.bnf - l.bf 4f - l.sfeqi r5,4 // l.bf - l.bf 5f -99: - l.nop - l.j 99b // should never happen - l.nop 1 - - // r2 is EEA - // r3 is trampoline address (physical) - // r4 is instruction - // r6 is physical(EEA) - // - // r5 - -2: // l.jal - - /* 19 20 aa aa l.movhi r9,0xaaaa - * a9 29 bb bb l.ori r9,0xbbbb - * - * where 0xaaaabbbb is EEA + 0x4 shifted right 2 - */ - - l.addi r6,r2,0x4 // this is 0xaaaabbbb - - // l.movhi r9,0xaaaa - l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9 - l.sh (TRAMP_SLOT_0+0x0)(r3),r5 - l.srli r5,r6,16 - l.sh (TRAMP_SLOT_0+0x2)(r3),r5 - - // l.ori r9,0xbbbb - l.ori r5,r0,0xa929 // 0xa929 == l.ori r9 - l.sh (TRAMP_SLOT_1+0x0)(r3),r5 - l.andi r5,r6,0xffff - l.sh (TRAMP_SLOT_1+0x2)(r3),r5 - - /* falthrough, need to set up new jump offset */ - - -0: // l.j - l.slli r6,r4,6 // original offset shifted left 6 - 2 -// l.srli r6,r6,6 // original offset shifted right 2 - - l.slli r4,r2,4 // old jump position: EEA shifted left 4 -// l.srli r4,r4,6 // old jump position: shifted right 2 - - l.addi r5,r3,0xc // new jump position (physical) - l.slli r5,r5,4 // new jump position: shifted left 4 - - // calculate new jump offset - // new_off = old_off + (old_jump - new_jump) - - l.sub r5,r4,r5 // old_jump - new_jump - l.add r5,r6,r5 // orig_off + (old_jump - new_jump) - l.srli r5,r5,6 // new offset shifted right 2 - - // r5 is new jump offset - // l.j has opcode 0x0... - l.sw TRAMP_SLOT_2(r3),r5 // write it back - - l.j trampoline_out - l.nop - -/* ----------------------------- */ - -3: // l.jalr - - /* 19 20 aa aa l.movhi r9,0xaaaa - * a9 29 bb bb l.ori r9,0xbbbb - * - * where 0xaaaabbbb is EEA + 0x4 shifted right 2 - */ - - l.addi r6,r2,0x4 // this is 0xaaaabbbb - - // l.movhi r9,0xaaaa - l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9 - l.sh (TRAMP_SLOT_0+0x0)(r3),r5 - l.srli r5,r6,16 - l.sh (TRAMP_SLOT_0+0x2)(r3),r5 - - // l.ori r9,0xbbbb - l.ori r5,r0,0xa929 // 0xa929 == l.ori r9 - l.sh (TRAMP_SLOT_1+0x0)(r3),r5 - l.andi r5,r6,0xffff - l.sh (TRAMP_SLOT_1+0x2)(r3),r5 - - l.lhz r5,(TRAMP_SLOT_2+0x0)(r3) // load hi part of jump instruction - l.andi r5,r5,0x3ff // clear out opcode part - l.ori r5,r5,0x4400 // opcode changed from l.jalr -> l.jr - l.sh (TRAMP_SLOT_2+0x0)(r3),r5 // write it back - - /* falthrough */ - -1: // l.jr - l.j trampoline_out - l.nop - -/* ----------------------------- */ - -4: // l.bnf -5: // l.bf - l.slli r6,r4,6 // original offset shifted left 6 - 2 -// l.srli r6,r6,6 // original offset shifted right 2 - - l.slli r4,r2,4 // old jump position: EEA shifted left 4 -// l.srli r4,r4,6 // old jump position: shifted right 2 - - l.addi r5,r3,0xc // new jump position (physical) - l.slli r5,r5,4 // new jump position: shifted left 4 - - // calculate new jump offset - // new_off = old_off + (old_jump - new_jump) - - l.add r6,r6,r4 // (orig_off + old_jump) - l.sub r6,r6,r5 // (orig_off + old_jump) - new_jump - l.srli r6,r6,6 // new offset shifted right 2 - - // r6 is new jump offset - l.lwz r4,(TRAMP_SLOT_2+0x0)(r3) // load jump instruction - l.srli r4,r4,16 - l.andi r4,r4,0xfc00 // get opcode part - l.slli r4,r4,16 - l.or r6,r4,r6 // l.b(n)f new offset - l.sw TRAMP_SLOT_2(r3),r6 // write it back - - /* we need to add l.j to EEA + 0x8 */ - tophys (r4,r2) // may not be needed (due to shifts down_ - l.addi r4,r4,(0x8 - 0x8) // jump target = r2 + 0x8 (compensate for 0x8) - // jump position = r5 + 0x8 (0x8 compensated) - l.sub r4,r4,r5 // jump offset = target - new_position + 0x8 - - l.slli r4,r4,4 // the amount of info in imediate of jump - l.srli r4,r4,6 // jump instruction with offset - l.sw TRAMP_SLOT_4(r3),r4 // write it to 4th slot - - /* fallthrough */ - -trampoline_out: - // set up new EPC to point to our trampoline code - LOAD_SYMBOL_2_GPR(r5,_immu_trampoline) - l.mtspr r0,r5,SPR_EPCR_BASE - - // immu_trampoline is (4x) CACHE_LINE aligned - // and only 6 instructions long, - // so we need to invalidate only 2 lines - - /* Establish cache block size - If BS=0, 16; - If BS=1, 32; - r14 contain block size - */ - l.mfspr r21,r0,SPR_ICCFGR - l.andi r21,r21,SPR_ICCFGR_CBS - l.srli r21,r21,7 - l.ori r23,r0,16 - l.sll r14,r23,r21 - - l.mtspr r0,r5,SPR_ICBIR - l.add r5,r5,r14 - l.mtspr r0,r5,SPR_ICBIR - - l.jr r9 - l.nop - - -/* - * DSCR: prints a string referenced by r3. - * - * PRMS: r3 - address of the first character of null - * terminated string to be printed - * - * PREQ: UART at UART_BASE_ADD has to be initialized - * - * POST: caller should be aware that r3, r9 are changed - */ -ENTRY(_emergency_print) - EMERGENCY_PRINT_STORE_GPR4 - EMERGENCY_PRINT_STORE_GPR5 - EMERGENCY_PRINT_STORE_GPR6 - EMERGENCY_PRINT_STORE_GPR7 -2: - l.lbz r7,0(r3) - l.sfeq r7,r0 - l.bf 9f - l.nop - -// putc: - l.movhi r4,hi(UART_BASE_ADD) - - l.addi r6,r0,0x20 -1: l.lbz r5,5(r4) - l.andi r5,r5,0x20 - l.sfeq r5,r6 - l.bnf 1b - l.nop - - l.sb 0(r4),r7 - - l.addi r6,r0,0x60 -1: l.lbz r5,5(r4) - l.andi r5,r5,0x60 - l.sfeq r5,r6 - l.bnf 1b - l.nop - - /* next character */ - l.j 2b - l.addi r3,r3,0x1 - -9: - EMERGENCY_PRINT_LOAD_GPR7 - EMERGENCY_PRINT_LOAD_GPR6 - EMERGENCY_PRINT_LOAD_GPR5 - EMERGENCY_PRINT_LOAD_GPR4 - l.jr r9 - l.nop - -ENTRY(_emergency_print_nr) - EMERGENCY_PRINT_STORE_GPR4 - EMERGENCY_PRINT_STORE_GPR5 - EMERGENCY_PRINT_STORE_GPR6 - EMERGENCY_PRINT_STORE_GPR7 - EMERGENCY_PRINT_STORE_GPR8 - - l.addi r8,r0,32 // shift register - -1: /* remove leading zeros */ - l.addi r8,r8,-0x4 - l.srl r7,r3,r8 - l.andi r7,r7,0xf - - /* don't skip the last zero if number == 0x0 */ - l.sfeqi r8,0x4 - l.bf 2f - l.nop - - l.sfeq r7,r0 - l.bf 1b - l.nop - -2: - l.srl r7,r3,r8 - - l.andi r7,r7,0xf - l.sflts r8,r0 - l.bf 9f - - l.sfgtui r7,0x9 - l.bnf 8f - l.nop - l.addi r7,r7,0x27 - -8: - l.addi r7,r7,0x30 -// putc: - l.movhi r4,hi(UART_BASE_ADD) - - l.addi r6,r0,0x20 -1: l.lbz r5,5(r4) - l.andi r5,r5,0x20 - l.sfeq r5,r6 - l.bnf 1b - l.nop - - l.sb 0(r4),r7 - - l.addi r6,r0,0x60 -1: l.lbz r5,5(r4) - l.andi r5,r5,0x60 - l.sfeq r5,r6 - l.bnf 1b - l.nop - - /* next character */ - l.j 2b - l.addi r8,r8,-0x4 - -9: - EMERGENCY_PRINT_LOAD_GPR8 - EMERGENCY_PRINT_LOAD_GPR7 - EMERGENCY_PRINT_LOAD_GPR6 - EMERGENCY_PRINT_LOAD_GPR5 - EMERGENCY_PRINT_LOAD_GPR4 - l.jr r9 - l.nop - - -/* - * This should be used for debugging only. - * It messes up the Linux early serial output - * somehow, so use it sparingly and essentially - * only if you need to debug something that goes wrong - * before Linux gets the early serial going. - * - * Furthermore, you'll have to make sure you set the - * UART_DEVISOR correctly according to the system - * clock rate. - * - * - */ - - - -#define SYS_CLK 20000000 -//#define SYS_CLK 1843200 -#define OR32_CONSOLE_BAUD 115200 -#define UART_DIVISOR SYS_CLK/(16*OR32_CONSOLE_BAUD) - -ENTRY(_early_uart_init) - l.movhi r3,hi(UART_BASE_ADD) - - l.addi r4,r0,0x7 - l.sb 0x2(r3),r4 - - l.addi r4,r0,0x0 - l.sb 0x1(r3),r4 - - l.addi r4,r0,0x3 - l.sb 0x3(r3),r4 - - l.lbz r5,3(r3) - l.ori r4,r5,0x80 - l.sb 0x3(r3),r4 - l.addi r4,r0,((UART_DIVISOR>>8) & 0x000000ff) - l.sb UART_DLM(r3),r4 - l.addi r4,r0,((UART_DIVISOR) & 0x000000ff) - l.sb UART_DLL(r3),r4 - l.sb 0x3(r3),r5 - - l.jr r9 - l.nop - -_string_copying_linux: - .string "\n\n\n\n\n\rCopying Linux... \0" - -_string_ok_booting: - .string "Ok, booting the kernel.\n\r\0" - -_string_unhandled_exception: - .string "\n\rRunarunaround: Unhandled exception 0x\0" - -_string_epc_prefix: - .string ": EPC=0x\0" - -_string_nl: - .string "\n\r\0" - - .global _string_esr_irq_bug -_string_esr_irq_bug: - .string "\n\rESR external interrupt bug, for details look into entry.S\n\r\0" - - - -/* ========================================[ page aligned structures ]=== */ - -/* - * .data section should be page aligned - * (look into arch/or32/kernel/vmlinux.lds) - */ - .section .data,"aw" - .align 8192 - .global empty_zero_page -empty_zero_page: - .space 8192 - - .global swapper_pg_dir -swapper_pg_dir: - .space 8192 - - .global _unhandled_stack -_unhandled_stack: - .space 8192 -_unhandled_stack_top: - -/* ============================================================[ EOF ]=== */ diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/idle.c b/ANDROID_3.4.5/arch/openrisc/kernel/idle.c deleted file mode 100644 index 7d618feb..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/idle.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * OpenRISC idle.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - * - * Idle daemon for or32. Idle daemon will handle any action - * that needs to be taken when the system becomes idle. - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/stddef.h> -#include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/tick.h> - -#include <asm/pgtable.h> -#include <asm/uaccess.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <asm/mmu.h> -#include <asm/cache.h> -#include <asm/pgalloc.h> - -void (*powersave) (void) = NULL; - -static inline void pm_idle(void) -{ - barrier(); -} - -void cpu_idle(void) -{ - set_thread_flag(TIF_POLLING_NRFLAG); - - /* endless idle loop with no priority at all */ - while (1) { - tick_nohz_idle_enter(); - rcu_idle_enter(); - - while (!need_resched()) { - check_pgt_cache(); - rmb(); - - clear_thread_flag(TIF_POLLING_NRFLAG); - - local_irq_disable(); - /* Don't trace irqs off for idle */ - stop_critical_timings(); - if (!need_resched() && powersave != NULL) - powersave(); - start_critical_timings(); - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); - } - - rcu_idle_exit(); - tick_nohz_idle_exit(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/init_task.c b/ANDROID_3.4.5/arch/openrisc/kernel/init_task.c deleted file mode 100644 index ca534082..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/init_task.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * OpenRISC init_task.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/init_task.h> -#include <linux/mqueue.h> -#include <linux/export.h> - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); - -/* - * Initial thread structure. - * - * We need to make sure that this is THREAD_SIZE aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry.. - */ -union thread_union init_thread_union __init_task_data = { - INIT_THREAD_INFO(init_task) -}; - -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/irq.c b/ANDROID_3.4.5/arch/openrisc/kernel/irq.c deleted file mode 100644 index 4bfead22..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/irq.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * OpenRISC irq.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/of.h> -#include <linux/ftrace.h> -#include <linux/irq.h> -#include <linux/seq_file.h> -#include <linux/kernel_stat.h> -#include <linux/export.h> - -#include <linux/irqflags.h> - -/* read interrupt enabled status */ -unsigned long arch_local_save_flags(void) -{ - return mfspr(SPR_SR) & (SPR_SR_IEE|SPR_SR_TEE); -} -EXPORT_SYMBOL(arch_local_save_flags); - -/* set interrupt enabled status */ -void arch_local_irq_restore(unsigned long flags) -{ - mtspr(SPR_SR, ((mfspr(SPR_SR) & ~(SPR_SR_IEE|SPR_SR_TEE)) | flags)); -} -EXPORT_SYMBOL(arch_local_irq_restore); - - -/* OR1K PIC implementation */ - -/* We're a couple of cycles faster than the generic implementations with - * these 'fast' versions. - */ - -static void or1k_pic_mask(struct irq_data *data) -{ - mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->irq)); -} - -static void or1k_pic_unmask(struct irq_data *data) -{ - mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->irq)); -} - -static void or1k_pic_ack(struct irq_data *data) -{ - /* EDGE-triggered interrupts need to be ack'ed in order to clear - * the latch. - * LEVER-triggered interrupts do not need to be ack'ed; however, - * ack'ing the interrupt has no ill-effect and is quicker than - * trying to figure out what type it is... - */ - - /* The OpenRISC 1000 spec says to write a 1 to the bit to ack the - * interrupt, but the OR1200 does this backwards and requires a 0 - * to be written... - */ - -#ifdef CONFIG_OR1K_1200 - /* There are two oddities with the OR1200 PIC implementation: - * i) LEVEL-triggered interrupts are latched and need to be cleared - * ii) the interrupt latch is cleared by writing a 0 to the bit, - * as opposed to a 1 as mandated by the spec - */ - - mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq)); -#else - WARN(1, "Interrupt handling possibily broken\n"); - mtspr(SPR_PICSR, (1UL << irq)); -#endif -} - -static void or1k_pic_mask_ack(struct irq_data *data) -{ - /* Comments for pic_ack apply here, too */ - -#ifdef CONFIG_OR1K_1200 - mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq)); -#else - WARN(1, "Interrupt handling possibily broken\n"); - mtspr(SPR_PICSR, (1UL << irq)); -#endif -} - -static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type) -{ - /* There's nothing to do in the PIC configuration when changing - * flow type. Level and edge-triggered interrupts are both - * supported, but it's PIC-implementation specific which type - * is handled. */ - - return irq_setup_alt_chip(data, flow_type); -} - -static inline int pic_get_irq(int first) -{ - int irq; - - irq = ffs(mfspr(SPR_PICSR) >> first); - - return irq ? irq + first - 1 : NO_IRQ; -} - -static void __init or1k_irq_init(void) -{ - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - - /* Disable all interrupts until explicitly requested */ - mtspr(SPR_PICMR, (0UL)); - - gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq); - ct = gc->chip_types; - - ct->chip.irq_unmask = or1k_pic_unmask; - ct->chip.irq_mask = or1k_pic_mask; - ct->chip.irq_ack = or1k_pic_ack; - ct->chip.irq_mask_ack = or1k_pic_mask_ack; - ct->chip.irq_set_type = or1k_pic_set_type; - - /* The OR1K PIC can handle both level and edge trigged - * interrupts in roughly the same manner - */ -#if 0 - /* FIXME: chip.type??? */ - ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK; -#endif - - irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0, - IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); -} - -void __init init_IRQ(void) -{ - or1k_irq_init(); -} - -void __irq_entry do_IRQ(struct pt_regs *regs) -{ - int irq = -1; - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - - while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) - generic_handle_irq(irq); - - irq_exit(); - set_irq_regs(old_regs); -} - -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - return intspec[0]; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/module.c b/ANDROID_3.4.5/arch/openrisc/kernel/module.c deleted file mode 100644 index 10ff50f0..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/module.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * OpenRISC module.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/moduleloader.h> -#include <linux/elf.h> - -int apply_relocate_add(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - unsigned int i; - Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; - Elf32_Sym *sym; - uint32_t *location; - uint32_t value; - - pr_debug("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr - + rel[i].r_offset; - - /* This is the symbol it is referring to. Note that all - undefined symbols have been resolved. */ - sym = (Elf32_Sym *)sechdrs[symindex].sh_addr - + ELF32_R_SYM(rel[i].r_info); - value = sym->st_value + rel[i].r_addend; - - switch (ELF32_R_TYPE(rel[i].r_info)) { - case R_OR32_32: - *location = value; - break; - case R_OR32_CONST: - location = (uint16_t *)location + 1; - *((uint16_t *)location) = (uint16_t) (value); - break; - case R_OR32_CONSTH: - location = (uint16_t *)location + 1; - *((uint16_t *)location) = (uint16_t) (value >> 16); - break; - case R_OR32_JUMPTARG: - value -= (uint32_t)location; - value >>= 2; - value &= 0x03ffffff; - value |= *location & 0xfc000000; - *location = value; - break; - default: - pr_err("module %s: Unknown relocation: %u\n", - me->name, ELF32_R_TYPE(rel[i].r_info)); - break; - } - } - - return 0; -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/or32_ksyms.c b/ANDROID_3.4.5/arch/openrisc/kernel/or32_ksyms.c deleted file mode 100644 index 83ccf7c0..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/or32_ksyms.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * OpenRISC or32_ksyms.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/module.h> -#include <linux/elfcore.h> -#include <linux/sched.h> -#include <linux/in6.h> -#include <linux/interrupt.h> -#include <linux/vmalloc.h> -#include <linux/semaphore.h> - -#include <asm/processor.h> -#include <asm/uaccess.h> -#include <asm/checksum.h> -#include <asm/io.h> -#include <asm/hardirq.h> -#include <asm/delay.h> -#include <asm/pgalloc.h> - -#define DECLARE_EXPORT(name) extern void name(void); EXPORT_SYMBOL(name) - -/* compiler generated symbols */ -DECLARE_EXPORT(__udivsi3); -DECLARE_EXPORT(__divsi3); -DECLARE_EXPORT(__umodsi3); -DECLARE_EXPORT(__modsi3); -DECLARE_EXPORT(__muldi3); -DECLARE_EXPORT(__ashrdi3); -DECLARE_EXPORT(__ashldi3); -DECLARE_EXPORT(__lshrdi3); - -EXPORT_SYMBOL(__copy_tofrom_user); diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/process.c b/ANDROID_3.4.5/arch/openrisc/kernel/process.c deleted file mode 100644 index 55210f37..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/process.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * OpenRISC process.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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 file handles the architecture-dependent parts of process handling... - */ - -#define __KERNEL_SYSCALLS__ -#include <stdarg.h> - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/stddef.h> -#include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/elfcore.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/init_task.h> -#include <linux/mqueue.h> -#include <linux/fs.h> - -#include <asm/uaccess.h> -#include <asm/pgtable.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <asm/spr_defs.h> - -#include <linux/smp.h> - -/* - * Pointer to Current thread info structure. - * - * Used at user space -> kernel transitions. - */ -struct thread_info *current_thread_info_set[NR_CPUS] = { &init_thread_info, }; - -void machine_restart(void) -{ - printk(KERN_INFO "*** MACHINE RESTART ***\n"); - __asm__("l.nop 1"); -} - -/* - * Similar to machine_power_off, but don't shut off power. Add code - * here to freeze the system for e.g. post-mortem debug purpose when - * possible. This halt has nothing to do with the idle halt. - */ -void machine_halt(void) -{ - printk(KERN_INFO "*** MACHINE HALT ***\n"); - __asm__("l.nop 1"); -} - -/* If or when software power-off is implemented, add code here. */ -void machine_power_off(void) -{ - printk(KERN_INFO "*** MACHINE POWER OFF ***\n"); - __asm__("l.nop 1"); -} - -void (*pm_power_off) (void) = machine_power_off; - -/* - * When a process does an "exec", machine state like FPU and debug - * registers need to be reset. This is a hook function for that. - * Currently we don't have any such state to reset, so this is empty. - */ -void flush_thread(void) -{ -} - -void show_regs(struct pt_regs *regs) -{ - extern void show_registers(struct pt_regs *regs); - - /* __PHX__ cleanup this mess */ - show_registers(regs); -} - -unsigned long thread_saved_pc(struct task_struct *t) -{ - return (unsigned long)user_regs(t->stack)->pc; -} - -void release_thread(struct task_struct *dead_task) -{ -} - -/* - * Copy the thread-specific (arch specific) info from the current - * process to the new one p - */ -extern asmlinkage void ret_from_fork(void); - -int -copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long unused, struct task_struct *p, struct pt_regs *regs) -{ - struct pt_regs *childregs; - struct pt_regs *kregs; - unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; - struct thread_info *ti; - unsigned long top_of_kernel_stack; - - top_of_kernel_stack = sp; - - p->set_child_tid = p->clear_child_tid = NULL; - - /* Copy registers */ - /* redzone */ - sp -= STACK_FRAME_OVERHEAD; - sp -= sizeof(struct pt_regs); - childregs = (struct pt_regs *)sp; - - /* Copy parent registers */ - *childregs = *regs; - - if ((childregs->sr & SPR_SR_SM) == 1) { - /* for kernel thread, set `current_thread_info' - * and stackptr in new task - */ - childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; - childregs->gpr[10] = (unsigned long)task_thread_info(p); - } else { - childregs->sp = usp; - } - - childregs->gpr[11] = 0; /* Result from fork() */ - - /* - * The way this works is that at some point in the future - * some task will call _switch to switch to the new task. - * That will pop off the stack frame created below and start - * the new task running at ret_from_fork. The new task will - * do some house keeping and then return from the fork or clone - * system call, using the stack frame created above. - */ - /* redzone */ - sp -= STACK_FRAME_OVERHEAD; - sp -= sizeof(struct pt_regs); - kregs = (struct pt_regs *)sp; - - ti = task_thread_info(p); - ti->ksp = sp; - - /* kregs->sp must store the location of the 'pre-switch' kernel stack - * pointer... for a newly forked process, this is simply the top of - * the kernel stack. - */ - kregs->sp = top_of_kernel_stack; - kregs->gpr[3] = (unsigned long)current; /* arg to schedule_tail */ - kregs->gpr[10] = (unsigned long)task_thread_info(p); - kregs->gpr[9] = (unsigned long)ret_from_fork; - - return 0; -} - -/* - * Set up a thread for executing a new program - */ -void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) -{ - unsigned long sr = regs->sr & ~SPR_SR_SM; - - set_fs(USER_DS); - memset(regs->gpr, 0, sizeof(regs->gpr)); - - regs->pc = pc; - regs->sr = sr; - regs->sp = sp; - -/* printk("start thread, ksp = %lx\n", current_thread_info()->ksp);*/ -} - -/* Fill in the fpu structure for a core dump. */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu) -{ - /* TODO */ - return 0; -} - -extern struct thread_info *_switch(struct thread_info *old_ti, - struct thread_info *new_ti); - -struct task_struct *__switch_to(struct task_struct *old, - struct task_struct *new) -{ - struct task_struct *last; - struct thread_info *new_ti, *old_ti; - unsigned long flags; - - local_irq_save(flags); - - /* current_set is an array of saved current pointers - * (one for each cpu). we need them at user->kernel transition, - * while we save them at kernel->user transition - */ - new_ti = new->stack; - old_ti = old->stack; - - current_thread_info_set[smp_processor_id()] = new_ti; - last = (_switch(old_ti, new_ti))->task; - - local_irq_restore(flags); - - return last; -} - -/* - * Write out registers in core dump format, as defined by the - * struct user_regs_struct - */ -void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs) -{ - dest[0] = 0; /* r0 */ - memcpy(dest+1, regs->gpr+1, 31*sizeof(unsigned long)); - dest[32] = regs->pc; - dest[33] = regs->sr; - dest[34] = 0; - dest[35] = 0; -} - -extern void _kernel_thread_helper(void); - -void __noreturn kernel_thread_helper(int (*fn) (void *), void *arg) -{ - do_exit(fn(arg)); -} - -/* - * Create a kernel thread. - */ -int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.gpr[20] = (unsigned long)fn; - regs.gpr[22] = (unsigned long)arg; - regs.sr = mfspr(SPR_SR); - regs.pc = (unsigned long)_kernel_thread_helper; - - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, - 0, ®s, 0, NULL, NULL); -} - -/* - * sys_execve() executes a new program. - */ -asmlinkage long _sys_execve(const char __user *name, - const char __user * const __user *argv, - const char __user * const __user *envp, - struct pt_regs *regs) -{ - int error; - char *filename; - - filename = getname(name); - error = PTR_ERR(filename); - - if (IS_ERR(filename)) - goto out; - - error = do_execve(filename, argv, envp, regs); - putname(filename); - -out: - return error; -} - -unsigned long get_wchan(struct task_struct *p) -{ - /* TODO */ - - return 0; -} - -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __res asm("r11") = __NR_execve; - register long __a asm("r3") = (long)(filename); - register long __b asm("r4") = (long)(argv); - register long __c asm("r5") = (long)(envp); - __asm__ volatile ("l.sys 1" - : "=r" (__res), "=r"(__a), "=r"(__b), "=r"(__c) - : "0"(__res), "1"(__a), "2"(__b), "3"(__c) - : "r6", "r7", "r8", "r12", "r13", "r15", - "r17", "r19", "r21", "r23", "r25", "r27", - "r29", "r31"); - __asm__ volatile ("l.nop"); - return __res; -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/prom.c b/ANDROID_3.4.5/arch/openrisc/kernel/prom.c deleted file mode 100644 index 5869e3fa..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/prom.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * OpenRISC prom.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - * - * Architecture specific procedures for creating, accessing and - * interpreting the device tree. - * - */ - -#include <stdarg.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/init.h> -#include <linux/threads.h> -#include <linux/spinlock.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/stringify.h> -#include <linux/delay.h> -#include <linux/initrd.h> -#include <linux/bitops.h> -#include <linux/module.h> -#include <linux/kexec.h> -#include <linux/debugfs.h> -#include <linux/irq.h> -#include <linux/memblock.h> -#include <linux/of_fdt.h> - -#include <asm/prom.h> -#include <asm/page.h> -#include <asm/processor.h> -#include <asm/irq.h> -#include <linux/io.h> -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/sections.h> -#include <asm/setup.h> - -extern char cmd_line[COMMAND_LINE_SIZE]; - -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - size &= PAGE_MASK; - memblock_add(base, size); -} - -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - -void __init early_init_devtree(void *params) -{ - void *alloc; - - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, TCE reserve, and more ... - */ - of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory, NULL); - - /* Save command line for /proc/cmdline and then parse parameters */ - strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); - - memblock_allow_resize(); - - /* We must copy the flattend device tree from init memory to regular - * memory because the device tree references the strings in it - * directly. - */ - - alloc = __va(memblock_alloc(initial_boot_params->totalsize, PAGE_SIZE)); - - memcpy(alloc, initial_boot_params, initial_boot_params->totalsize); - - initial_boot_params = alloc; -} - -#ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) -{ - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; -} -#endif diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/ptrace.c b/ANDROID_3.4.5/arch/openrisc/kernel/ptrace.c deleted file mode 100644 index e71781d2..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/ptrace.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * OpenRISC ptrace.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2005 Gyorgy Jeney <nog@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <stddef.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/string.h> - -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/audit.h> -#include <linux/regset.h> -#include <linux/tracehook.h> -#include <linux/elf.h> - -#include <asm/thread_info.h> -#include <asm/segment.h> -#include <asm/page.h> -#include <asm/pgtable.h> - -/* - * Copy the thread state to a regset that can be interpreted by userspace. - * - * It doesn't matter what our internal pt_regs structure looks like. The - * important thing is that we export a consistent view of the thread state - * to userspace. As such, we need to make sure that the regset remains - * ABI compatible as defined by the struct user_regs_struct: - * - * (Each item is a 32-bit word) - * r0 = 0 (exported for clarity) - * 31 GPRS r1-r31 - * PC (Program counter) - * SR (Supervision register) - */ -static int genregs_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user * ubuf) -{ - const struct pt_regs *regs = task_pt_regs(target); - int ret; - - /* r0 */ - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 0, 4); - - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - regs->gpr+1, 4, 4*32); - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - ®s->pc, 4*32, 4*33); - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - ®s->sr, 4*33, 4*34); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - 4*34, -1); - - return ret; -} - -/* - * Set the thread state from a regset passed in via ptrace - */ -static int genregs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user * ubuf) -{ - struct pt_regs *regs = task_pt_regs(target); - int ret; - - /* ignore r0 */ - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); - /* r1 - r31 */ - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - regs->gpr+1, 4, 4*32); - /* PC */ - if (!ret) - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - ®s->pc, 4*32, 4*33); - /* - * Skip SR and padding... userspace isn't allowed to changes bits in - * the Supervision register - */ - if (!ret) - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - 4*33, -1); - - return ret; -} - -/* - * Define the register sets available on OpenRISC under Linux - */ -enum or1k_regset { - REGSET_GENERAL, -}; - -static const struct user_regset or1k_regsets[] = { - [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, - .n = ELF_NGREG, - .size = sizeof(long), - .align = sizeof(long), - .get = genregs_get, - .set = genregs_set, - }, -}; - -static const struct user_regset_view user_or1k_native_view = { - .name = "or1k", - .e_machine = EM_OPENRISC, - .regsets = or1k_regsets, - .n = ARRAY_SIZE(or1k_regsets), -}; - -const struct user_regset_view *task_user_regset_view(struct task_struct *task) -{ - return &user_or1k_native_view; -} - -/* - * does not yet catch signals sent when the child dies. - * in exit.c or in signal.c. - */ - - -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. - */ -void ptrace_disable(struct task_struct *child) -{ - pr_debug("ptrace_disable(): TODO\n"); - - user_disable_single_step(child); - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); -} - -long arch_ptrace(struct task_struct *child, long request, unsigned long addr, - unsigned long data) -{ - int ret; - - switch (request) { - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -/* - * Notification of system call entry/exit - * - triggered by current->work.syscall_trace - */ -asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) -{ - long ret = 0; - - if (test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs)) - /* - * Tracing decided this syscall should not happen. - * We'll return a bogus call number to get an ENOSYS - * error, but leave the original number in <something>. - */ - ret = -1L; - - audit_syscall_entry(audit_arch(), regs->gpr[11], - regs->gpr[3], regs->gpr[4], - regs->gpr[5], regs->gpr[6]); - - return ret ? : regs->gpr[11]; -} - -asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) -{ - int step; - - audit_syscall_exit(regs); - - step = test_thread_flag(TIF_SINGLESTEP); - if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, step); -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/setup.c b/ANDROID_3.4.5/arch/openrisc/kernel/setup.c deleted file mode 100644 index f4d5bedc..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/setup.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * OpenRISC setup.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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 file handles the architecture-dependent parts of initialization - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/stddef.h> -#include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/console.h> -#include <linux/init.h> -#include <linux/bootmem.h> -#include <linux/seq_file.h> -#include <linux/serial.h> -#include <linux/initrd.h> -#include <linux/of_fdt.h> -#include <linux/of.h> -#include <linux/memblock.h> -#include <linux/device.h> -#include <linux/of_platform.h> - -#include <asm/segment.h> -#include <asm/pgtable.h> -#include <asm/types.h> -#include <asm/setup.h> -#include <asm/io.h> -#include <asm/cpuinfo.h> -#include <asm/delay.h> - -#include "vmlinux.h" - -char __initdata cmd_line[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; - -static unsigned long __init setup_memory(void) -{ - unsigned long bootmap_size; - unsigned long ram_start_pfn; - unsigned long free_ram_start_pfn; - unsigned long ram_end_pfn; - phys_addr_t memory_start, memory_end; - struct memblock_region *region; - - memory_end = memory_start = 0; - - /* Find main memory where is the kernel */ - for_each_memblock(memory, region) { - memory_start = region->base; - memory_end = region->base + region->size; - printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__, - memory_start, memory_end); - } - - if (!memory_end) { - panic("No memory!"); - } - - ram_start_pfn = PFN_UP(memory_start); - /* free_ram_start_pfn is first page after kernel */ - free_ram_start_pfn = PFN_UP(__pa(&_end)); - ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM()); - - max_pfn = ram_end_pfn; - - /* - * initialize the boot-time allocator (with low memory only). - * - * This makes the memory from the end of the kernel to the end of - * RAM usable. - * init_bootmem sets the global values min_low_pfn, max_low_pfn. - */ - bootmap_size = init_bootmem(free_ram_start_pfn, - ram_end_pfn - ram_start_pfn); - free_bootmem(PFN_PHYS(free_ram_start_pfn), - (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT); - reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size, - BOOTMEM_DEFAULT); - - for_each_memblock(reserved, region) { - printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n", - (u32) region->base, (u32) region->size); - reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT); - } - - return ram_end_pfn; -} - -struct cpuinfo cpuinfo; - -static void print_cpuinfo(void) -{ - unsigned long upr = mfspr(SPR_UPR); - unsigned long vr = mfspr(SPR_VR); - unsigned int version; - unsigned int revision; - - version = (vr & SPR_VR_VER) >> 24; - revision = (vr & SPR_VR_REV); - - printk(KERN_INFO "CPU: OpenRISC-%x (revision %d) @%d MHz\n", - version, revision, cpuinfo.clock_frequency / 1000000); - - if (!(upr & SPR_UPR_UP)) { - printk(KERN_INFO - "-- no UPR register... unable to detect configuration\n"); - return; - } - - if (upr & SPR_UPR_DCP) - printk(KERN_INFO - "-- dcache: %4d bytes total, %2d bytes/line, %d way(s)\n", - cpuinfo.dcache_size, cpuinfo.dcache_block_size, 1); - else - printk(KERN_INFO "-- dcache disabled\n"); - if (upr & SPR_UPR_ICP) - printk(KERN_INFO - "-- icache: %4d bytes total, %2d bytes/line, %d way(s)\n", - cpuinfo.icache_size, cpuinfo.icache_block_size, 1); - else - printk(KERN_INFO "-- icache disabled\n"); - - if (upr & SPR_UPR_DMP) - printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n", - 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), - 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW)); - if (upr & SPR_UPR_IMP) - printk(KERN_INFO "-- immu: %4d entries, %lu way(s)\n", - 1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2), - 1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW)); - - printk(KERN_INFO "-- additional features:\n"); - if (upr & SPR_UPR_DUP) - printk(KERN_INFO "-- debug unit\n"); - if (upr & SPR_UPR_PCUP) - printk(KERN_INFO "-- performance counters\n"); - if (upr & SPR_UPR_PMP) - printk(KERN_INFO "-- power management\n"); - if (upr & SPR_UPR_PICP) - printk(KERN_INFO "-- PIC\n"); - if (upr & SPR_UPR_TTP) - printk(KERN_INFO "-- timer\n"); - if (upr & SPR_UPR_CUP) - printk(KERN_INFO "-- custom unit(s)\n"); -} - -void __init setup_cpuinfo(void) -{ - struct device_node *cpu; - unsigned long iccfgr, dccfgr; - unsigned long cache_set_size, cache_ways; - - cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481"); - if (!cpu) - panic("No compatible CPU found in device tree...\n"); - - iccfgr = mfspr(SPR_ICCFGR); - cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW); - cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); - cpuinfo.icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7); - cpuinfo.icache_size = - cache_set_size * cache_ways * cpuinfo.icache_block_size; - - dccfgr = mfspr(SPR_DCCFGR); - cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW); - cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); - cpuinfo.dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7); - cpuinfo.dcache_size = - cache_set_size * cache_ways * cpuinfo.dcache_block_size; - - if (of_property_read_u32(cpu, "clock-frequency", - &cpuinfo.clock_frequency)) { - printk(KERN_WARNING - "Device tree missing CPU 'clock-frequency' parameter." - "Assuming frequency 25MHZ" - "This is probably not what you want."); - } - - of_node_put(cpu); - - print_cpuinfo(); -} - -/** - * or32_early_setup - * - * Handles the pointer to the device tree that this kernel is to use - * for establishing the available platform devices. - * - * Falls back on built-in device tree in case null pointer is passed. - */ - -void __init or32_early_setup(unsigned int fdt) -{ - if (fdt) { - early_init_devtree((void*) fdt); - printk(KERN_INFO "FDT at 0x%08x\n", fdt); - } else { - early_init_devtree(__dtb_start); - printk(KERN_INFO "Compiled-in FDT at %p\n", __dtb_start); - } -} - -static int __init openrisc_device_probe(void) -{ - of_platform_populate(NULL, NULL, NULL, NULL); - - return 0; -} - -device_initcall(openrisc_device_probe); - -static inline unsigned long extract_value_bits(unsigned long reg, - short bit_nr, short width) -{ - return (reg >> bit_nr) & (0 << width); -} - -static inline unsigned long extract_value(unsigned long reg, unsigned long mask) -{ - while (!(mask & 0x1)) { - reg = reg >> 1; - mask = mask >> 1; - } - return mask & reg; -} - -void __init detect_unit_config(unsigned long upr, unsigned long mask, - char *text, void (*func) (void)) -{ - if (text != NULL) - printk("%s", text); - - if (upr & mask) { - if (func != NULL) - func(); - else - printk("present\n"); - } else - printk("not present\n"); -} - -/* - * calibrate_delay - * - * Lightweight calibrate_delay implementation that calculates loops_per_jiffy - * from the clock frequency passed in via the device tree - * - */ - -void __cpuinit calibrate_delay(void) -{ - const int *val; - struct device_node *cpu = NULL; - cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481"); - val = of_get_property(cpu, "clock-frequency", NULL); - if (!val) - panic("no cpu 'clock-frequency' parameter in device tree"); - loops_per_jiffy = *val / HZ; - pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", - loops_per_jiffy / (500000 / HZ), - (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy); -} - -void __init setup_arch(char **cmdline_p) -{ - unsigned long max_low_pfn; - - unflatten_device_tree(); - - setup_cpuinfo(); - - /* process 1's initial memory region is the kernel code/data */ - init_mm.start_code = (unsigned long)&_stext; - init_mm.end_code = (unsigned long)&_etext; - init_mm.end_data = (unsigned long)&_edata; - init_mm.brk = (unsigned long)&_end; - -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = (unsigned long)&__initrd_start; - initrd_end = (unsigned long)&__initrd_end; - if (initrd_start == initrd_end) { - initrd_start = 0; - initrd_end = 0; - } - initrd_below_start_ok = 1; -#endif - - /* setup bootmem allocator */ - max_low_pfn = setup_memory(); - - /* paging_init() sets up the MMU and marks all pages as reserved */ - paging_init(); - -#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) - if (!conswitchp) - conswitchp = &dummy_con; -#endif - - *cmdline_p = cmd_line; - - printk(KERN_INFO "OpenRISC Linux -- http://openrisc.net\n"); -} - -static int show_cpuinfo(struct seq_file *m, void *v) -{ - unsigned long vr; - int version, revision; - - vr = mfspr(SPR_VR); - version = (vr & SPR_VR_VER) >> 24; - revision = vr & SPR_VR_REV; - - return seq_printf(m, - "cpu\t\t: OpenRISC-%x\n" - "revision\t: %d\n" - "frequency\t: %ld\n" - "dcache size\t: %d bytes\n" - "dcache block size\t: %d bytes\n" - "icache size\t: %d bytes\n" - "icache block size\t: %d bytes\n" - "immu\t\t: %d entries, %lu ways\n" - "dmmu\t\t: %d entries, %lu ways\n" - "bogomips\t: %lu.%02lu\n", - version, - revision, - loops_per_jiffy * HZ, - cpuinfo.dcache_size, - cpuinfo.dcache_block_size, - cpuinfo.icache_size, - cpuinfo.icache_block_size, - 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), - 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW), - 1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2), - 1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW), - (loops_per_jiffy * HZ) / 500000, - ((loops_per_jiffy * HZ) / 5000) % 100); -} - -static void *c_start(struct seq_file *m, loff_t * pos) -{ - /* We only have one CPU... */ - return *pos < 1 ? (void *)1 : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t * pos) -{ - ++*pos; - return NULL; -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/signal.c b/ANDROID_3.4.5/arch/openrisc/kernel/signal.c deleted file mode 100644 index e9707432..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/signal.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * OpenRISC signal.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/errno.h> -#include <linux/wait.h> -#include <linux/ptrace.h> -#include <linux/unistd.h> -#include <linux/stddef.h> -#include <linux/tracehook.h> - -#include <asm/processor.h> -#include <asm/ucontext.h> -#include <asm/uaccess.h> - -#define DEBUG_SIG 0 - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -asmlinkage long -_sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) -{ - return do_sigaltstack(uss, uoss, regs->sp); -} - -struct rt_sigframe { - struct siginfo *pinfo; - void *puc; - struct siginfo info; - struct ucontext uc; - unsigned char retcode[16]; /* trampoline code */ -}; - -static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) -{ - unsigned int err = 0; - - /* Alwys make any pending restarted system call return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - /* - * Restore the regs from &sc->regs. - * (sc is already checked for VERIFY_READ since the sigframe was - * checked in sys_sigreturn previously) - */ - if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long))) - goto badframe; - if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long))) - goto badframe; - if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long))) - goto badframe; - - /* make sure the SM-bit is cleared so user-mode cannot fool us */ - regs->sr &= ~SPR_SR_SM; - - /* TODO: the other ports use regs->orig_XX to disable syscall checks - * after this completes, but we don't use that mechanism. maybe we can - * use it now ? - */ - - return err; - -badframe: - return 1; -} - -asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; - sigset_t set; - stack_t st; - - /* - * Since we stacked the signal on a dword boundary, - * then frame should be dword aligned here. If it's - * not, then the user is trying to mess with us. - */ - if (((long)frame) & 3) - goto badframe; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); - - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) - goto badframe; - - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->sp); - - return regs->gpr[11]; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -/* - * Set up a signal frame. - */ - -static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, - unsigned long mask) -{ - int err = 0; - - /* copy the regs */ - - err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long)); - err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long)); - err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long)); - - /* then some other stuff */ - - err |= __put_user(mask, &sc->oldmask); - - return err; -} - -static inline unsigned long align_sigframe(unsigned long sp) -{ - return sp & ~3UL; -} - -/* - * Work out where the signal frame should go. It's either on the user stack - * or the alternate stack. - */ - -static inline void __user *get_sigframe(struct k_sigaction *ka, - struct pt_regs *regs, size_t frame_size) -{ - unsigned long sp = regs->sp; - int onsigstack = on_sig_stack(sp); - - /* redzone */ - sp -= STACK_FRAME_OVERHEAD; - - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) { - if (current->sas_ss_size) - sp = current->sas_ss_sp + current->sas_ss_size; - } - - sp = align_sigframe(sp - frame_size); - - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (onsigstack && !likely(on_sig_stack(sp))) - return (void __user *)-1L; - - return (void __user *)sp; -} - -/* grab and setup a signal frame. - * - * basically we stack a lot of state info, and arrange for the - * user-mode program to return to the kernel using either a - * trampoline which performs the syscall sigreturn, or a provided - * user-mode trampoline. - */ -static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe *frame; - unsigned long return_ip; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - - if (ka->sa.sa_flags & SA_SIGINFO) - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto give_sigsegv; - - /* Clear all the bits of the ucontext we don't use. */ - err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(NULL, &frame->uc.uc_link); - err |= __put_user((void *)current->sas_ss_sp, - &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); - - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - - if (err) - goto give_sigsegv; - - /* trampoline - the desired return ip is the retcode itself */ - return_ip = (unsigned long)&frame->retcode; - /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */ - err |= __put_user(0xa960, (short *)(frame->retcode + 0)); - err |= __put_user(__NR_rt_sigreturn, (short *)(frame->retcode + 2)); - err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4)); - err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8)); - - if (err) - goto give_sigsegv; - - /* TODO what is the current->exec_domain stuff and invmap ? */ - - /* Set up registers for signal handler */ - regs->pc = (unsigned long)ka->sa.sa_handler; /* what we enter NOW */ - regs->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */ - regs->gpr[3] = (unsigned long)sig; /* arg 1: signo */ - regs->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */ - regs->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */ - - /* actually move the usp to reflect the stacked frame */ - regs->sp = (unsigned long)frame; - - return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; -} - -static inline int -handle_signal(unsigned long sig, - siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs *regs) -{ - int ret; - - ret = setup_rt_frame(sig, ka, info, oldset, regs); - if (ret) - return ret; - - block_sigmask(ka, sig); - - return 0; -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - * - * Also note that the regs structure given here as an argument, is the latest - * pushed pt_regs. It may or may not be the same as the first pushed registers - * when the initial usermode->kernelmode transition took place. Therefore - * we can use user_mode(regs) to see if we came directly from kernel or user - * mode below. - */ - -void do_signal(struct pt_regs *regs) -{ - siginfo_t info; - int signr; - struct k_sigaction ka; - - /* - * We want the common case to go fast, which - * is why we may in certain cases get here from - * kernel mode. Just return without doing anything - * if so. - */ - if (!user_mode(regs)) - return; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - - /* If we are coming out of a syscall then we need - * to check if the syscall was interrupted and wants to be - * restarted after handling the signal. If so, the original - * syscall number is put back into r11 and the PC rewound to - * point at the l.sys instruction that resulted in the - * original syscall. Syscall results other than the four - * below mean that the syscall executed to completion and no - * restart is necessary. - */ - if (regs->orig_gpr11) { - int restart = 0; - - switch (regs->gpr[11]) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - /* Restart if there is no signal handler */ - restart = (signr <= 0); - break; - case -ERESTARTSYS: - /* Restart if there no signal handler or - * SA_RESTART flag is set */ - restart = (signr <= 0 || (ka.sa.sa_flags & SA_RESTART)); - break; - case -ERESTARTNOINTR: - /* Always restart */ - restart = 1; - break; - } - - if (restart) { - if (regs->gpr[11] == -ERESTART_RESTARTBLOCK) - regs->gpr[11] = __NR_restart_syscall; - else - regs->gpr[11] = regs->orig_gpr11; - regs->pc -= 4; - } else { - regs->gpr[11] = -EINTR; - } - } - - if (signr <= 0) { - /* no signal to deliver so we just put the saved sigmask - * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } - - } else { /* signr > 0 */ - sigset_t *oldset; - - if (current_thread_info()->flags & _TIF_RESTORE_SIGMASK) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - - /* Whee! Actually deliver the signal. */ - if (!handle_signal(signr, &info, &ka, oldset, regs)) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - - tracehook_signal_handler(signr, &info, &ka, regs, - test_thread_flag(TIF_SINGLESTEP)); - } - - return; -} - -asmlinkage void do_notify_resume(struct pt_regs *regs) -{ - if (current_thread_info()->flags & _TIF_SIGPENDING) - do_signal(regs); - - if (current_thread_info()->flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/sys_call_table.c b/ANDROID_3.4.5/arch/openrisc/kernel/sys_call_table.c deleted file mode 100644 index e1f8ce8c..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/sys_call_table.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * OpenRISC sys_call_table.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/syscalls.h> -#include <linux/signal.h> -#include <linux/unistd.h> - -#include <asm/syscalls.h> - -#undef __SYSCALL -#define __SYSCALL(nr, call) [nr] = (call), - -void *sys_call_table[__NR_syscalls] = { -#include <asm/unistd.h> -}; diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/sys_or32.c b/ANDROID_3.4.5/arch/openrisc/kernel/sys_or32.c deleted file mode 100644 index 57060084..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/sys_or32.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * OpenRISC sys_or32.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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 file contains various random system calls that - * have a non-standard calling sequence on some platforms. - * Since we don't have to do any backwards compatibility, our - * versions are done in the most "normal" way possible. - */ - -#include <linux/errno.h> -#include <linux/syscalls.h> -#include <linux/mm.h> - -#include <asm/syscalls.h> - -/* These are secondary entry points as the primary entry points are defined in - * entry.S where we add the 'regs' parameter value - */ - -asmlinkage long _sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tid, int __user *child_tid, - struct pt_regs *regs) -{ - long ret; - - /* FIXME: Is alignment necessary? */ - /* newsp = ALIGN(newsp, 4); */ - - if (!newsp) - newsp = regs->sp; - - ret = do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); - - return ret; -} - -asmlinkage int _sys_fork(struct pt_regs *regs) -{ -#ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); -#else - return -EINVAL; -#endif -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/time.c b/ANDROID_3.4.5/arch/openrisc/kernel/time.c deleted file mode 100644 index 7c52e949..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/time.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * OpenRISC time.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - */ - -#include <linux/kernel.h> -#include <linux/time.h> -#include <linux/timex.h> -#include <linux/interrupt.h> -#include <linux/ftrace.h> - -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/irq.h> -#include <linux/io.h> - -#include <asm/cpuinfo.h> - -static int openrisc_timer_set_next_event(unsigned long delta, - struct clock_event_device *dev) -{ - u32 c; - - /* Read 32-bit counter value, add delta, mask off the low 28 bits. - * We're guaranteed delta won't be bigger than 28 bits because the - * generic timekeeping code ensures that for us. - */ - c = mfspr(SPR_TTCR); - c += delta; - c &= SPR_TTMR_TP; - - /* Set counter and enable interrupt. - * Keep timer in continuous mode always. - */ - mtspr(SPR_TTMR, SPR_TTMR_CR | SPR_TTMR_IE | c); - - return 0; -} - -static void openrisc_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - pr_debug(KERN_INFO "%s: periodic\n", __func__); - BUG(); - break; - case CLOCK_EVT_MODE_ONESHOT: - pr_debug(KERN_INFO "%s: oneshot\n", __func__); - break; - case CLOCK_EVT_MODE_UNUSED: - pr_debug(KERN_INFO "%s: unused\n", __func__); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - pr_debug(KERN_INFO "%s: shutdown\n", __func__); - break; - case CLOCK_EVT_MODE_RESUME: - pr_debug(KERN_INFO "%s: resume\n", __func__); - break; - } -} - -/* This is the clock event device based on the OR1K tick timer. - * As the timer is being used as a continuous clock-source (required for HR - * timers) we cannot enable the PERIODIC feature. The tick timer can run using - * one-shot events, so no problem. - */ - -static struct clock_event_device clockevent_openrisc_timer = { - .name = "openrisc_timer_clockevent", - .features = CLOCK_EVT_FEAT_ONESHOT, - .rating = 300, - .set_next_event = openrisc_timer_set_next_event, - .set_mode = openrisc_timer_set_mode, -}; - -static inline void timer_ack(void) -{ - /* Clear the IP bit and disable further interrupts */ - /* This can be done very simply... we just need to keep the timer - running, so just maintain the CR bits while clearing the rest - of the register - */ - mtspr(SPR_TTMR, SPR_TTMR_CR); -} - -/* - * The timer interrupt is mostly handled in generic code nowadays... this - * function just acknowledges the interrupt and fires the event handler that - * has been set on the clockevent device by the generic time management code. - * - * This function needs to be called by the timer exception handler and that's - * all the exception handler needs to do. - */ - -irqreturn_t __irq_entry timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - struct clock_event_device *evt = &clockevent_openrisc_timer; - - timer_ack(); - - /* - * update_process_times() expects us to have called irq_enter(). - */ - irq_enter(); - evt->event_handler(evt); - irq_exit(); - - set_irq_regs(old_regs); - - return IRQ_HANDLED; -} - -static __init void openrisc_clockevent_init(void) -{ - clockevent_openrisc_timer.cpumask = cpumask_of(0); - - /* We only have 28 bits */ - clockevents_config_and_register(&clockevent_openrisc_timer, - cpuinfo.clock_frequency, - 100, 0x0fffffff); - -} - -/** - * Clocksource: Based on OpenRISC timer/counter - * - * This sets up the OpenRISC Tick Timer as a clock source. The tick timer - * is 32 bits wide and runs at the CPU clock frequency. - */ - -static cycle_t openrisc_timer_read(struct clocksource *cs) -{ - return (cycle_t) mfspr(SPR_TTCR); -} - -static struct clocksource openrisc_timer = { - .name = "openrisc_timer", - .rating = 200, - .read = openrisc_timer_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init openrisc_timer_init(void) -{ - if (clocksource_register_hz(&openrisc_timer, cpuinfo.clock_frequency)) - panic("failed to register clocksource"); - - /* Enable the incrementer: 'continuous' mode with interrupt disabled */ - mtspr(SPR_TTMR, SPR_TTMR_CR); - - return 0; -} - -void __init time_init(void) -{ - u32 upr; - - upr = mfspr(SPR_UPR); - if (!(upr & SPR_UPR_TTP)) - panic("Linux not supported on devices without tick timer"); - - openrisc_timer_init(); - openrisc_clockevent_init(); -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/traps.c b/ANDROID_3.4.5/arch/openrisc/kernel/traps.c deleted file mode 100644 index 5cce3960..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/traps.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * OpenRISC traps.c - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - * - * Here we handle the break vectors not used by the system call - * mechanism, as well as some general stack/register dumping - * things. - * - */ - -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/kmod.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/kallsyms.h> -#include <asm/uaccess.h> - -#include <asm/segment.h> -#include <asm/io.h> -#include <asm/pgtable.h> - -extern char _etext, _stext; - -int kstack_depth_to_print = 0x180; - -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - return p > (void *)tinfo && p < (void *)tinfo + THREAD_SIZE - 3; -} - -void show_trace(struct task_struct *task, unsigned long *stack) -{ - struct thread_info *context; - unsigned long addr; - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - - while (valid_stack_ptr(context, stack)) { - addr = *stack++; - if (__kernel_text_address(addr)) { - printk(" [<%08lx>]", addr); - print_symbol(" %s", addr); - printk("\n"); - } - } - printk(" =======================\n"); -} - -/* displays a short stack trace */ -void show_stack(struct task_struct *task, unsigned long *esp) -{ - unsigned long addr, *stack; - int i; - - if (esp == NULL) - esp = (unsigned long *)&esp; - - stack = esp; - - printk("Stack dump [0x%08lx]:\n", (unsigned long)esp); - for (i = 0; i < kstack_depth_to_print; i++) { - if (kstack_end(stack)) - break; - if (__get_user(addr, stack)) { - /* This message matches "failing address" marked - s390 in ksymoops, so lines containing it will - not be filtered out by ksymoops. */ - printk("Failing address 0x%lx\n", (unsigned long)stack); - break; - } - stack++; - - printk("sp + %02d: 0x%08lx\n", i * 4, addr); - } - printk("\n"); - - show_trace(task, esp); - - return; -} - -void show_trace_task(struct task_struct *tsk) -{ - /* - * TODO: SysRq-T trace dump... - */ -} - -/* - * The architecture-independent backtrace generator - */ -void dump_stack(void) -{ - unsigned long stack; - - show_stack(current, &stack); -} -EXPORT_SYMBOL(dump_stack); - -void show_registers(struct pt_regs *regs) -{ - int i; - int in_kernel = 1; - unsigned long esp; - - esp = (unsigned long)(®s->sp); - if (user_mode(regs)) - in_kernel = 0; - - printk("CPU #: %d\n" - " PC: %08lx SR: %08lx SP: %08lx\n", - smp_processor_id(), regs->pc, regs->sr, regs->sp); - printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n", - 0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]); - printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n", - regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]); - printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n", - regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]); - printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n", - regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]); - printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n", - regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]); - printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n", - regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]); - printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n", - regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); - printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", - regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx\n", - regs->gpr[11], regs->orig_gpr11); - - printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, (unsigned long)current); - /* - * When in-kernel, we also print out the stack and code at the - * time of the fault.. - */ - if (in_kernel) { - - printk("\nStack: "); - show_stack(NULL, (unsigned long *)esp); - - printk("\nCode: "); - if (regs->pc < PAGE_OFFSET) - goto bad; - - for (i = -24; i < 24; i++) { - unsigned char c; - if (__get_user(c, &((unsigned char *)regs->pc)[i])) { -bad: - printk(" Bad PC value."); - break; - } - - if (i == 0) - printk("(%02x) ", c); - else - printk("%02x ", c); - } - } - printk("\n"); -} - -void nommu_dump_state(struct pt_regs *regs, - unsigned long ea, unsigned long vector) -{ - int i; - unsigned long addr, stack = regs->sp; - - printk("\n\r[nommu_dump_state] :: ea %lx, vector %lx\n\r", ea, vector); - - printk("CPU #: %d\n" - " PC: %08lx SR: %08lx SP: %08lx\n", - 0, regs->pc, regs->sr, regs->sp); - printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n", - 0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]); - printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n", - regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]); - printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n", - regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]); - printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n", - regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]); - printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n", - regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]); - printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n", - regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]); - printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n", - regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); - printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", - regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx\n", - regs->gpr[11], regs->orig_gpr11); - - printk("Process %s (pid: %d, stackpage=%08lx)\n", - ((struct task_struct *)(__pa(current)))->comm, - ((struct task_struct *)(__pa(current)))->pid, - (unsigned long)current); - - printk("\nStack: "); - printk("Stack dump [0x%08lx]:\n", (unsigned long)stack); - for (i = 0; i < kstack_depth_to_print; i++) { - if (((long)stack & (THREAD_SIZE - 1)) == 0) - break; - stack++; - - printk("%lx :: sp + %02d: 0x%08lx\n", stack, i * 4, - *((unsigned long *)(__pa(stack)))); - } - printk("\n"); - - printk("Call Trace: "); - i = 1; - while (((long)stack & (THREAD_SIZE - 1)) != 0) { - addr = *((unsigned long *)__pa(stack)); - stack++; - - if (kernel_text_address(addr)) { - if (i && ((i % 6) == 0)) - printk("\n "); - printk(" [<%08lx>]", addr); - i++; - } - } - printk("\n"); - - printk("\nCode: "); - - for (i = -24; i < 24; i++) { - unsigned char c; - c = ((unsigned char *)(__pa(regs->pc)))[i]; - - if (i == 0) - printk("(%02x) ", c); - else - printk("%02x ", c); - } - printk("\n"); -} - -/* This is normally the 'Oops' routine */ -void die(const char *str, struct pt_regs *regs, long err) -{ - - console_verbose(); - printk("\n%s#: %04lx\n", str, err & 0xffff); - show_registers(regs); -#ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION - printk("\n\nUNHANDLED_EXCEPTION: entering infinite loop\n"); - - /* shut down interrupts */ - local_irq_disable(); - - __asm__ __volatile__("l.nop 1"); - do {} while (1); -#endif - do_exit(SIGSEGV); -} - -/* This is normally the 'Oops' routine */ -void die_if_kernel(const char *str, struct pt_regs *regs, long err) -{ - if (user_mode(regs)) - return; - - die(str, regs, err); -} - -void unhandled_exception(struct pt_regs *regs, int ea, int vector) -{ - printk("Unable to handle exception at EA =0x%x, vector 0x%x", - ea, vector); - die("Oops", regs, 9); -} - -void __init trap_init(void) -{ - /* Nothing needs to be done */ -} - -asmlinkage void do_trap(struct pt_regs *regs, unsigned long address) -{ - siginfo_t info; - memset(&info, 0, sizeof(info)); - info.si_signo = SIGTRAP; - info.si_code = TRAP_TRACE; - info.si_addr = (void *)address; - force_sig_info(SIGTRAP, &info, current); - - regs->pc += 4; -} - -asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address) -{ - siginfo_t info; - - if (user_mode(regs)) { - /* Send a SIGSEGV */ - info.si_signo = SIGSEGV; - info.si_errno = 0; - /* info.si_code has been set above */ - info.si_addr = (void *)address; - force_sig_info(SIGSEGV, &info, current); - } else { - printk("KERNEL: Unaligned Access 0x%.8lx\n", address); - show_registers(regs); - die("Die:", regs, address); - } - -} - -asmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address) -{ - siginfo_t info; - - if (user_mode(regs)) { - /* Send a SIGBUS */ - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; - force_sig_info(SIGBUS, &info, current); - } else { /* Kernel mode */ - printk("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address); - show_registers(regs); - die("Die:", regs, address); - } -} - -asmlinkage void do_illegal_instruction(struct pt_regs *regs, - unsigned long address) -{ - siginfo_t info; - - if (user_mode(regs)) { - /* Send a SIGILL */ - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_code = ILL_ILLOPC; - info.si_addr = (void *)address; - force_sig_info(SIGBUS, &info, current); - } else { /* Kernel mode */ - printk("KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n", - address); - show_registers(regs); - die("Die:", regs, address); - } -} diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.h b/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.h deleted file mode 100644 index ee842a2d..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __OPENRISC_VMLINUX_H_ -#define __OPENRISC_VMLINUX_H_ - -extern char _stext, _etext, _edata, _end; -#ifdef CONFIG_BLK_DEV_INITRD -extern char __initrd_start, __initrd_end; -extern char __initramfs_start; -#endif - -extern u32 __dtb_start[]; - -#endif diff --git a/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.lds.S b/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.lds.S deleted file mode 100644 index 2d69a853..00000000 --- a/ANDROID_3.4.5/arch/openrisc/kernel/vmlinux.lds.S +++ /dev/null @@ -1,115 +0,0 @@ -/* - * OpenRISC vmlinux.lds.S - * - * Linux architectural port borrowing liberally from similar works of - * others. All original copyrights apply as per the original source - * declaration. - * - * Modifications for the OpenRISC architecture: - * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> - * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> - * - * 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. - * - * ld script for OpenRISC architecture - */ - -/* TODO - * - clean up __offset & stuff - * - change all 8192 aligment to PAGE !!! - * - recheck if all aligments are really needed - */ - -# define LOAD_OFFSET PAGE_OFFSET -# define LOAD_BASE PAGE_OFFSET - -#include <asm/page.h> -#include <asm/cache.h> -#include <asm-generic/vmlinux.lds.h> - -OUTPUT_FORMAT("elf32-or32", "elf32-or32", "elf32-or32") -jiffies = jiffies_64 + 4; - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = LOAD_BASE ; - - /* _s_kernel_ro must be page aligned */ - . = ALIGN(PAGE_SIZE); - _s_kernel_ro = .; - - .text : AT(ADDR(.text) - LOAD_OFFSET) - { - _stext = .; - TEXT_TEXT - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - IRQENTRY_TEXT - *(.fixup) - *(.text.__*) - _etext = .; - } - /* TODO: Check if fixup and text.__* are really necessary - * fixup is definitely necessary - */ - - _sdata = .; - - /* Page alignment required for RO_DATA_SECTION */ - RO_DATA_SECTION(PAGE_SIZE) - _e_kernel_ro = .; - - /* Whatever comes after _e_kernel_ro had better be page-aligend, too */ - - /* 32 here is cacheline size... recheck this */ - RW_DATA_SECTION(32, PAGE_SIZE, PAGE_SIZE) - - _edata = .; - - EXCEPTION_TABLE(4) - NOTES - - /* Init code and data */ - . = ALIGN(PAGE_SIZE); - __init_begin = .; - - HEAD_TEXT_SECTION - - /* Page aligned */ - INIT_TEXT_SECTION(PAGE_SIZE) - - /* Align __setup_start on 16 byte boundary */ - INIT_DATA_SECTION(16) - - PERCPU_SECTION(L1_CACHE_BYTES) - - __init_end = .; - - . = ALIGN(PAGE_SIZE); - .initrd : AT(ADDR(.initrd) - LOAD_OFFSET) - { - __initrd_start = .; - *(.initrd) - __initrd_end = .; - FILL (0); - . = ALIGN (PAGE_SIZE); - } - - __vmlinux_end = .; /* last address of the physical file */ - - BSS_SECTION(0, 0, 0x20) - - _end = .; - - /* Throw in the debugging sections */ - STABS_DEBUG - DWARF_DEBUG - - /* Sections to be discarded -- must be last */ - DISCARDS -} |