diff --git a/.editorconfig b/.editorconfig index 581101f..1bec2c2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,4 +14,9 @@ indent_style = tab [tools/**/*.txt] charset = utf-8 indent_style = tab -indent_size = 8 \ No newline at end of file +indent_size = 8 + +[resources/project/include/*.h] +charset = utf-8 +indent_style = tab +indent_size = 8 diff --git a/resources/project/Makefile b/resources/project/Makefile new file mode 100644 index 0000000..8e0fad8 --- /dev/null +++ b/resources/project/Makefile @@ -0,0 +1,61 @@ +export LD_PRELOAD = + +MEM_DEF = -DMEMSTART=0x80040000 -DMEMSIZE=0x10000 +CFLAGS = -O3 -fno-pic -mno-branch-likely -mno-abicalls -msoft-float -fno-builtin -mips1 -I include -EL +AFLAGS = -O2 -fno-pic -mno-abicalls -msoft-float -fno-builtin -mips1 -I include -EL + +export CROSS_COMPILE ?= mipsel-linux-gnu- +export MEM_DEF +export CFLAGS + +OBJDIR = obj +TARGET = ./src/main.o + +all: + mkdir -p $(OBJDIR) + make generate + +libtinyc.a : + make -C lib $@ + +generate: axi_ram.bin convert + ./convert axi_ram.bin $(OBJDIR)/ + +axi_ram.bin: main.elf + ${CROSS_COMPILE}objcopy -O binary -j .text -j .data $(OBJDIR)/$< $(OBJDIR)/$@ + +main.elf: start.o libtinyc.a bin.lds $(TARGET) + ${CROSS_COMPILE}ld -g -EL -T bin.lds start.o $(TARGET) lib/libtinyc.a -o $(OBJDIR)/$@ + ${CROSS_COMPILE}objdump -alD $(OBJDIR)/$@ > $(OBJDIR)/test.s + +$(TARGET): + make -C src + +bin.lds: bin.lds.S + ${CROSS_COMPILE}gcc -EL -E -P -Umips -D_LOADER -U_MAIN $(MEM_DEF) $< -o $@ + +start.o: start.S + ${CROSS_COMPILE}gcc $(CFLAGS) -c $< -nostdinc -nostdlib + +convert: convert.c + clang -o convert convert.c + +clean: + rm -f *.o *.bin *.elf *.a testbin *.s *.vlog *.coe *.data *.mif + rm -rf obj + make -C lib clean + make -C src clean +reset: + make clean + rm -f bin.lds convert + +help: + @echo "####################################################################" + @echo "### help for compiling our awesome project ###" + @echo "####################################################################" + @echo "### options: ###" + @echo "### make : get compiled result, which is saved in ./obj ###" + @echo "### make clean: remove *.o, *.a, and ./obj ###" + @echo "### make reset: "make clean" and remove convert, bin.lds ###" + @echo "### make help : show help information ###" + @echo "####################################################################" diff --git a/resources/project/bin.lds.S b/resources/project/bin.lds.S new file mode 100644 index 0000000..0377c3c --- /dev/null +++ b/resources/project/bin.lds.S @@ -0,0 +1,89 @@ +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0xbfc00000; + .text : + { + _ftext = . ; + *(.text) + rodata_end = .; + } =0 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0 + .data : AT(rodata_end) + { + *(.rodata*) + *(.reginfo) + *(.init) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + _fdata = . ; + _stack = _fdata + MEMSIZE -32; + *(.data) + *(.data*) + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + _gp = ALIGN(16) + 0x7ff0; + *(.got.plt) *(.got) + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + *(.sdata) + *(.lit8) + *(.lit4) +} + _edata = .; + PROVIDE (edata = .); + + data_size = SIZEOF(.data); + data_load_start = LOADADDR(.data); + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(8); + _end = . ; + PROVIDE (end = .); + + . = ALIGN(32); + + .bigdata : { *(.bigdata) } + + . = ALIGN(256); + _heap = . ; + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .MIPS.abiflags : { *(.MIPS.abiflags) } =0 +} diff --git a/resources/project/convert.c b/resources/project/convert.c new file mode 100644 index 0000000..ab7a1f4 --- /dev/null +++ b/resources/project/convert.c @@ -0,0 +1,84 @@ +#include +#include +#include + +void binary_out(FILE* out,unsigned char* mem) +{ + char tmp; + unsigned char num[8]; + num[0] = 1; + num[1] = 2; + num[2] = 4; + num[3] = 8; + num[4] = 16; + num[5] = 32; + num[6] = 64; + num[7] = 128; + for(int i=3;i>=0;i--) + { + for(int j=7;j>=0;j--) + { + if( (mem[i] & num[j] ) != 0) + tmp = '1'; + else + tmp = '0'; + fprintf(out,"%c",tmp); + } + } + fprintf(out,"\n"); + return; +} + +int main(int argc, char** argv) +{ + FILE *in; + FILE *out; + + if(argc < 3){ + fprintf(stderr, "Usage: convert main.bin main.data directory\n"); + return 1; + } + + char str_bin[256]; + char str_coe[256], str_mif[256]; + strncpy(str_bin, argv[2], 256); + strncpy(str_coe, argv[2], 256); + strncpy(str_mif, argv[2], 256); + strncat(str_bin, argv[1], 256); + strncat(str_coe, "axi_ram.coe", 256); + strncat(str_mif, "axi_ram.mif", 256); + //printf("%s\n%s\n%s\n%s\n%s\n%s\n", str_bin, str_data, str_inst_coe, str_inst_mif, str_data_coe, str_data_mif); + + int i,j,k; + unsigned char mem[32]; + + in = fopen(str_bin, "rb"); + out = fopen(str_coe,"w"); + + fprintf(out, "memory_initialization_radix = 16;\n"); + fprintf(out, "memory_initialization_vector =\n"); + while(!feof(in)) { + if(fread(mem,1,4,in)!=4) { + fprintf(out, "%02x%02x%02x%02x\n", mem[3], mem[2], mem[1], mem[0]); + break; + } + fprintf(out, "%02x%02x%02x%02x\n", mem[3], mem[2], mem[1],mem[0]); + } + fclose(in); + fclose(out); + + in = fopen(str_bin, "rb"); + out = fopen(str_mif,"w"); + + while(!feof(in)) { + if(fread(mem,1,4,in)!=4) { + binary_out(out,mem); + break; + } + binary_out(out,mem); + } + fclose(in); + fclose(out); + + return 0; +} diff --git a/resources/project/include/asm/addrspace.h b/resources/project/include/asm/addrspace.h new file mode 100644 index 0000000..8dfe736 --- /dev/null +++ b/resources/project/include/asm/addrspace.h @@ -0,0 +1,154 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 99 Ralf Baechle + * Copyright (C) 2000, 2002 Maciej W. Rozycki + * Copyright (C) 1990, 1999 by Silicon Graphics, Inc. + */ +#ifndef _ASM_ADDRSPACE_H +#define _ASM_ADDRSPACE_H + +//#include + +/* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ATYPE_ +#define _ATYPE32_ +#define _ATYPE64_ +#define _CONST64_(x) x +#else +#define _ATYPE_ __PTRDIFF_TYPE__ +#define _ATYPE32_ int +#define _ATYPE64_ __s64 +#ifdef CONFIG_64BIT +#define _CONST64_(x) x ## L +#else +#define _CONST64_(x) x ## LL +#endif +#endif + +/* + * 32-bit MIPS address spaces + */ +#ifdef __ASSEMBLY__ +#define _ACAST32_ +#define _ACAST64_ +#else +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ +#endif + +/* + * Returns the kernel segment base of a given address + */ +#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000) + +/* + * Returns the physical address of a CKSEGx / XKPHYS address + */ +#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) +#define XPHYSADDR(a) ((_ACAST64_(a)) & \ + _CONST64_(0x000000ffffffffff)) + +#ifdef CONFIG_64BIT + +/* + * Memory segments (64bit kernel mode addresses) + * The compatibility segments use the full 64-bit sign extended value. Note + * the R8000 doesn't have them so don't reference these in generic MIPS code. + */ +#define XKUSEG _CONST64_(0x0000000000000000) +#define XKSSEG _CONST64_(0x4000000000000000) +#define XKPHYS _CONST64_(0x8000000000000000) +#define XKSEG _CONST64_(0xc000000000000000) +#define CKSEG0 _CONST64_(0xffffffff80000000) +#define CKSEG1 _CONST64_(0xffffffffa0000000) +#define CKSSEG _CONST64_(0xffffffffc0000000) +#define CKSEG3 _CONST64_(0xffffffffe0000000) + +#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0) +#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1) +#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2) +#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3) + +#else + +#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) +#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) +#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) +#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) + +/* + * Map an address to a certain kernel segment + */ +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) + +/* + * Memory segments (32bit kernel mode addresses) + * These are the traditional names used in the 32-bit universe. + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 + +#define CKUSEG 0x00000000 +#define CKSEG0 0x80000000 +#define CKSEG1 0xa0000000 +#define CKSEG2 0xc0000000 +#define CKSEG3 0xe0000000 + +#endif + +/* + * Cache modes for XKPHYS address conversion macros + */ +#define K_CALG_COH_EXCL1_NOL2 0 +#define K_CALG_COH_SHRL1_NOL2 1 +#define K_CALG_UNCACHED 2 +#define K_CALG_NONCOHERENT 3 +#define K_CALG_COH_EXCL 4 +#define K_CALG_COH_SHAREABLE 5 +#define K_CALG_NOTUSED 6 +#define K_CALG_UNCACHED_ACCEL 7 + +/* + * 64-bit address conversions + */ +#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p)) +#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p)) +#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) +#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \ + (_CONST64_(cm) << 59) | (a)) + +/* + * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting + * the region, 3 bits for the CCA mode. This leaves 59 bits of which the + * R8000 implements most with its 48-bit physical address space. + */ +#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */ + +#ifndef CONFIG_CPU_R8000 + +/* + * The R8000 doesn't have the 32-bit compat spaces so we don't define them + * in order to catch bugs in the source code. + */ + +#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000) +#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ + +#endif + +#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK) +#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE) + +#endif /* _ASM_ADDRSPACE_H */ diff --git a/resources/project/include/asm/asm.h b/resources/project/include/asm/asm.h new file mode 100644 index 0000000..00aa7f4 --- /dev/null +++ b/resources/project/include/asm/asm.h @@ -0,0 +1,254 @@ +/* $OpenBSD: asm.h,v 1.2 1998/03/16 09:03:02 pefo Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (C) 1989 Digital Equipment Corporation. + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies. + * Digital Equipment Corporation makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef _MIPS_ASM_H +#define _MIPS_ASM_H + +#include + +#ifndef ABICALLS +#define ABICALLS .abicalls +#endif + +#if defined(ABICALLS) && !defined(_KERNEL) + ABICALLS +#endif + +#define RCSID(x) + +/* + * Define how to access unaligned data word + */ +#if defined(__MIPSEL__) +#define LWLO lwl +#define LWHI lwr +#define SWLO swl +#define SWHI swr +#else +#if defined(__MIPSEB__) +#define LWLO lwr +#define LWHI lwl +#define SWLO swr +#define SWHI swl +#else +#error "__MIPSEL__ or __MIPSEB__ must be defined" +#endif +#endif + +/* + * Code for setting gp reg if abicalls are used. + */ +#if defined(ABICALLS) && !defined(_KERNEL) +#define ABISETUP \ + .set noreorder; \ + .cpload t9; \ + .set reorder; +#else +#define ABISETUP +#endif + +/* + * Define -pg profile entry code. + */ +#if defined(GPROF) || defined(PROF) +#define MCOUNT \ + subu sp, sp, 32; \ + .cprestore 16; \ + sw ra, 28(sp); \ + sw gp, 24(sp); \ + .set noat; \ + .set noreorder; \ + move AT, ra; \ + jal _mcount; \ + subu sp, sp, 8; \ + lw ra, 28(sp); \ + addu sp, sp, 32; \ + .set reorder; \ + .set at; +#else +#define MCOUNT +#endif + +/* + * LEAF(x) + * + * Declare a leaf routine. + */ +#define LEAF(x) \ + .align 3; \ + .globl x; \ + .ent x, 0; \ +x: ; \ + .frame sp, 0, ra; \ + ABISETUP \ + MCOUNT + +#define ALEAF(x) \ + .globl x; \ +x: + +/* + * NLEAF(x) + * + * Declare a non-profiled leaf routine. + */ +#define NLEAF(x) \ + .align 3; \ + .globl x; \ + .ent x, 0; \ +x: ; \ + .frame sp, 0, ra; \ + ABISETUP + +/* + * NON_LEAF(x) + * + * Declare a non-leaf routine (a routine that makes other C calls). + */ +#define NON_LEAF(x, fsize, retpc) \ + .align 3; \ + .globl x; \ + .ent x, 0; \ +x: ; \ + .frame sp, fsize, retpc; \ + ABISETUP \ + MCOUNT + +/* + * NNON_LEAF(x) + * + * Declare a non-profiled non-leaf routine + * (a routine that makes other C calls). + */ +#define NNON_LEAF(x, fsize, retpc) \ + .align 3; \ + .globl x; \ + .ent x, 0; \ +x: ; \ + .frame sp, fsize, retpc \ + ABISETUP + +/* + * END(x) + * + * Mark end of a procedure. + */ +#define END(x) \ + .end x + +/* + * Macros to panic and printf from assembly language. + */ +#define PANIC(msg) \ + la a0, 9f; \ + jal panic; \ + MSG(msg) + +#define PRINTF(msg) \ + la a0, 9f; \ + jal printf; \ + MSG(msg) + +#define MSG(msg) \ + .rdata; \ +9: .asciiz msg; \ + .text + +#define ASMSTR(str) \ + .asciiz str; \ + .align 3 + +#if (_MIPS_SZPTR == 32) +#define PTR_ADD add +#define PTR_ADDU addu +#define PTR_ADDI addi +#define PTR_ADDIU addiu +#define PTR_SUB sub +#define PTR_SUBU subu +#define PTR_L lw +#define PTR_S sw +#define PTR_LA la +#define PTR_LI li +#define PTR_SLL sll +#define PTR_SLLV sllv +#define PTR_SRL srl +#define PTR_SRLV srlv +#define PTR_SRA sra +#define PTR_SRAV srav + +#define PTR_SCALESHIFT 2 + +#define PTR .word +#define PTRSIZE 4 +#define PTRLOG 2 +#endif + +#if (_MIPS_SZPTR == 64) +#define PTR_ADD dadd +#define PTR_ADDU daddu +#define PTR_ADDI daddi +#define PTR_ADDIU daddiu +#define PTR_SUB dsub +#define PTR_SUBU dsubu +#define PTR_L ld +#define PTR_S sd +#define PTR_LA dla +#define PTR_LI dli +#define PTR_SLL dsll +#define PTR_SLLV dsllv +#define PTR_SRL dsrl +#define PTR_SRLV dsrlv +#define PTR_SRA dsra +#define PTR_SRAV dsrav + +#define PTR_SCALESHIFT 3 + +#define PTR .dword +#define PTRSIZE 8 +#define PTRLOG 3 +#endif + +#endif /* !_MIPS_ASM_H */ diff --git a/resources/project/include/asm/cacheops.h b/resources/project/include/asm/cacheops.h new file mode 100644 index 0000000..256ad2c --- /dev/null +++ b/resources/project/include/asm/cacheops.h @@ -0,0 +1,85 @@ +/* + * Cache operations for the cache instruction. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H + +/* + * Cache Operations available on all MIPS processors with R4000-style caches + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else +#define Hit_Invalidate_I 0x10 +#endif +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_SD 0x1b +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f + +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R10000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff --git a/resources/project/include/asm/context.h b/resources/project/include/asm/context.h new file mode 100644 index 0000000..737b876 --- /dev/null +++ b/resources/project/include/asm/context.h @@ -0,0 +1,200 @@ +/************************************************************************** +* * +* PROJECT : MIPS port for uC/OS-II * +* * +* MODULE : CONTEXT.h * +* * +* AUTHOR : Michael Anburaj * +* URL : http://geocities.com/michaelanburaj/ * +* EMAIL: michaelanburaj@hotmail.com * +* * +* PROCESSOR : MIPS 4Kc (32 bit RISC) - ATLAS board * +* * +* TOOL-CHAIN : SDE & Cygnus * +* * +* DESCRIPTION : * +* Context switch macros. * +* * +**************************************************************************/ + + +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ + + +/* ********************************************************************* */ +/* Module configuration */ + + +/* ********************************************************************* */ +/* Interface macro & data definition */ + +#ifdef __ASSEMBLER__ + + +// push context: at, v0-v1,a0-a3,t0-t9,s0-s7,gp,fp,ra, & pc +#define STORE_REG_RET(Retaddr) \ + .set noat; \ + .set noreorder; \ + subu sp,120; \ + sw ra,0(sp); \ + sw fp,4(sp); \ + sw gp,8(sp); \ + sw t9,12(sp); \ + sw t8,16(sp); \ + sw s7,20(sp); \ + sw s6,24(sp); \ + sw s5,28(sp); \ + sw s4,32(sp); \ + sw s3,36(sp); \ + sw s2,40(sp); \ + sw s1,44(sp); \ + sw s0,48(sp); \ + sw t7,52(sp); \ + sw t6,56(sp); \ + sw t5,60(sp); \ + sw t4,64(sp); \ + sw t3,68(sp); \ + sw t2,72(sp); \ + sw t1,76(sp); \ + sw t0,80(sp); \ + sw a3,84(sp); \ + sw a2,88(sp); \ + sw a1,92(sp); \ + sw a0,96(sp); \ + sw v1,100(sp); \ + sw v0,104(sp); \ + sw AT,108(sp); \ + mfc0 t0,c0_status; \ + sw t0,112(sp); \ + sw Retaddr,116(sp); \ + .set at + +// pop context (normal execution): at, v0-v1,a0-a3,t0-t9,s0-s7,gp,fp,ra, & pc +#define RESTORE_REG_RET() \ + .set noat; \ + .set noreorder; \ + lw ra,0(sp); \ + lw fp,4(sp); \ + lw gp,8(sp); \ + lw t9,12(sp); \ + lw t8,16(sp); \ + lw s7,20(sp); \ + lw s6,24(sp); \ + lw s5,28(sp); \ + lw s4,32(sp); \ + lw s3,36(sp); \ + lw s2,40(sp); \ + lw s1,44(sp); \ + lw s0,48(sp); \ + lw t7,52(sp); \ + lw t6,56(sp); \ + lw t5,60(sp); \ + lw t4,64(sp); \ + lw t3,68(sp); \ + lw t2,72(sp); \ + lw t1,76(sp); \ + lw t0,80(sp); \ + lw a3,84(sp); \ + lw a2,88(sp); \ + lw a1,92(sp); \ + lw a0,96(sp); \ + lw v1,100(sp); \ + lw v0,104(sp); \ + lw AT,108(sp); \ + lw k0,112(sp); \ + mtc0 k0,c0_status; \ + lw k0,116(sp); \ + addu sp,120; \ + jr k0; \ + nop; \ + .set at + +// pop context: at, v0-v1,a0-a3,t0-t9,s0-s7,gp,fp,ra, & pc +#define RESTORE_REG_ERET() \ + .set noat; \ + .set noreorder; \ + lw ra,0(sp); \ + lw fp,4(sp); \ + lw gp,8(sp); \ + lw t9,12(sp); \ + lw t8,16(sp); \ + lw s7,20(sp); \ + lw s6,24(sp); \ + lw s5,28(sp); \ + lw s4,32(sp); \ + lw s3,36(sp); \ + lw s2,40(sp); \ + lw s1,44(sp); \ + lw s0,48(sp); \ + lw t7,52(sp); \ + lw t6,56(sp); \ + lw t5,60(sp); \ + lw t4,64(sp); \ + lw t3,68(sp); \ + lw t2,72(sp); \ + lw t1,76(sp); \ + lw t0,80(sp); \ + lw a3,84(sp); \ + lw a2,88(sp); \ + lw a1,92(sp); \ + lw a0,96(sp); \ + lw v1,100(sp); \ + lw v0,104(sp); \ + lw AT,108(sp); \ + lw k0,112(sp); \ + mtc0 k0,c0_status; \ + lw k0,116(sp); \ + mtc0 k0,c0_epc; \ + addu sp,120; \ + eret; \ + nop; \ + .set at + +#else +struct pt_regs { + int ra; + int fp; + int gp; + int t9; + int t8; + int s7; + int s6; + int s5; + int s4; + int s3; + int s2; + int s1; + int s0; + int t7; + int t6; + int t5; + int t4; + int t3; + int t2; + int t1; + int t0; + int a3; + int a2; + int a1; + int a0; + int v1; + int v0; + int AT; + int status; + int epc; +}; +#endif /* _ASSEMBLER_ */ + + +/* ********************************************************************* */ +/* Interface function definition */ + + +/* ********************************************************************* */ + +#ifdef __cplusplus +} +#endif + +#endif /*__CONTEXT_H__*/ diff --git a/resources/project/include/asm/mipsregs.h b/resources/project/include/asm/mipsregs.h new file mode 100644 index 0000000..6b6d937 --- /dev/null +++ b/resources/project/include/asm/mipsregs.h @@ -0,0 +1,1586 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. + * Modified for further R[236]000 support by Paul M. Antoine, 1996. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 07 MIPS Technologies, Inc. + * Copyright (C) 2003, 2004 Maciej W. Rozycki + */ +#ifndef _ASM_MIPSREGS_H +#define _ASM_MIPSREGS_H + +//#include +//#include +//#include + +/* + * The following macros are especially useful for __asm__ + * inline assembler. + */ +#ifndef __STR +#define __STR(x) #x +#endif +#ifndef STR +#define STR(x) __STR(x) +#endif + +/* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ULCAST_ +#else +#define _ULCAST_ (unsigned long) +#endif + +/* + * Coprocessor 0 register names + */ +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONF $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_INFO $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_CONFIG $16 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_XCONTEXT $20 +#define CP0_FRAMEMASK $21 +#define CP0_DIAGNOSTIC $22 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFORMANCE $25 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_TAGHI $29 +#define CP0_ERROREPC $30 +#define CP0_DESAVE $31 + +/* + * R4640/R4650 cp0 register names. These registers are listed + * here only for completeness; without MMU these CPUs are not useable + * by Linux. A future ELKS port might take make Linux run on them + * though ... + */ +#define CP0_IBASE $0 +#define CP0_IBOUND $1 +#define CP0_DBASE $2 +#define CP0_DBOUND $3 +#define CP0_CALG $17 +#define CP0_IWATCH $18 +#define CP0_DWATCH $19 + +/* + * Coprocessor 0 Set 1 register names + */ +#define CP0_S1_DERRADDR0 $26 +#define CP0_S1_DERRADDR1 $27 +#define CP0_S1_INTCONTROL $20 + +/* + * Coprocessor 0 Set 2 register names + */ +#define CP0_S2_SRSCTL $12 /* MIPSR2 */ + +/* + * Coprocessor 0 Set 3 register names + */ +#define CP0_S3_SRSMAP $12 /* MIPSR2 */ + +/* + * TX39 Series + */ +#define CP0_TX39_CACHE $7 + +/* + * Coprocessor 1 (FPU) register names + */ +#define CP1_REVISION $0 +#define CP1_STATUS $31 + +/* + * FPU Status Register Values + */ +/* + * Status Register Values + */ + +#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ +#define FPU_CSR_COND 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ +#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ +#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ +#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ +#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ +#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ +#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ + +/* + * Bits 18 - 20 of the FPU Status Register will be read as 0, + * and should be written as zero. + */ +#define FPU_CSR_RSVD 0x001c0000 + +/* + * X the exception cause indicator + * E the exception enable + * S the sticky/flag bit +*/ +#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_UNI_X 0x00020000 +#define FPU_CSR_INV_X 0x00010000 +#define FPU_CSR_DIV_X 0x00008000 +#define FPU_CSR_OVF_X 0x00004000 +#define FPU_CSR_UDF_X 0x00002000 +#define FPU_CSR_INE_X 0x00001000 + +#define FPU_CSR_ALL_E 0x00000f80 +#define FPU_CSR_INV_E 0x00000800 +#define FPU_CSR_DIV_E 0x00000400 +#define FPU_CSR_OVF_E 0x00000200 +#define FPU_CSR_UDF_E 0x00000100 +#define FPU_CSR_INE_E 0x00000080 + +#define FPU_CSR_ALL_S 0x0000007c +#define FPU_CSR_INV_S 0x00000040 +#define FPU_CSR_DIV_S 0x00000020 +#define FPU_CSR_OVF_S 0x00000010 +#define FPU_CSR_UDF_S 0x00000008 +#define FPU_CSR_INE_S 0x00000004 + +/* Bits 0 and 1 of FPU Status Register specify the rounding mode */ +#define FPU_CSR_RM 0x00000003 +#define FPU_CSR_RN 0x0 /* nearest */ +#define FPU_CSR_RZ 0x1 /* towards zero */ +#define FPU_CSR_RU 0x2 /* towards +Infinity */ +#define FPU_CSR_RD 0x3 /* towards -Infinity */ + + +/* + * Values for PageMask register + */ +#ifdef CONFIG_CPU_VR41XX + +/* Why doesn't stupidity hurt ... */ + +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 + +#else + +#define PM_4K 0x00000000 +#define PM_8K 0x00002000 +#define PM_16K 0x00006000 +#define PM_32K 0x0000e000 +#define PM_64K 0x0001e000 +#define PM_128K 0x0003e000 +#define PM_256K 0x0007e000 +#define PM_512K 0x000fe000 +#define PM_1M 0x001fe000 +#define PM_2M 0x003fe000 +#define PM_4M 0x007fe000 +#define PM_8M 0x00ffe000 +#define PM_16M 0x01ffe000 +#define PM_32M 0x03ffe000 +#define PM_64M 0x07ffe000 +#define PM_256M 0x1fffe000 +#define PM_1G 0x7fffe000 + +#endif + +/* + * Default page size for a given kernel configuration + */ +#ifdef CONFIG_PAGE_SIZE_4KB +#define PM_DEFAULT_MASK PM_4K +#elif defined(CONFIG_PAGE_SIZE_8KB) +#define PM_DEFAULT_MASK PM_8K +#elif defined(CONFIG_PAGE_SIZE_16KB) +#define PM_DEFAULT_MASK PM_16K +#elif defined(CONFIG_PAGE_SIZE_32KB) +#define PM_DEFAULT_MASK PM_32K +#elif defined(CONFIG_PAGE_SIZE_64KB) +#define PM_DEFAULT_MASK PM_64K +#else +#error Bad page size configuration! +#endif + +/* + * Default huge tlb size for a given kernel configuration + */ +#ifdef CONFIG_PAGE_SIZE_4KB +#define PM_HUGE_MASK PM_1M +#elif defined(CONFIG_PAGE_SIZE_8KB) +#define PM_HUGE_MASK PM_4M +#elif defined(CONFIG_PAGE_SIZE_16KB) +#define PM_HUGE_MASK PM_16M +#elif defined(CONFIG_PAGE_SIZE_32KB) +#define PM_HUGE_MASK PM_64M +#elif defined(CONFIG_PAGE_SIZE_64KB) +#define PM_HUGE_MASK PM_256M +#elif defined(CONFIG_HUGETLB_PAGE) +#error Bad page size configuration for hugetlbfs! +#endif + +/* + * Values used for computation of new tlb entries + */ +#define PL_4K 12 +#define PL_16K 14 +#define PL_64K 16 +#define PL_256K 18 +#define PL_1M 20 +#define PL_4M 22 +#define PL_16M 24 +#define PL_64M 26 +#define PL_256M 28 + +/* + * R4x00 interrupt enable / cause bits + */ +#define IE_SW0 (_ULCAST_(1) << 8) +#define IE_SW1 (_ULCAST_(1) << 9) +#define IE_IRQ0 (_ULCAST_(1) << 10) +#define IE_IRQ1 (_ULCAST_(1) << 11) +#define IE_IRQ2 (_ULCAST_(1) << 12) +#define IE_IRQ3 (_ULCAST_(1) << 13) +#define IE_IRQ4 (_ULCAST_(1) << 14) +#define IE_IRQ5 (_ULCAST_(1) << 15) + +/* + * R4x00 interrupt cause bits + */ +#define C_SW0 (_ULCAST_(1) << 8) +#define C_SW1 (_ULCAST_(1) << 9) +#define C_IRQ0 (_ULCAST_(1) << 10) +#define C_IRQ1 (_ULCAST_(1) << 11) +#define C_IRQ2 (_ULCAST_(1) << 12) +#define C_IRQ3 (_ULCAST_(1) << 13) +#define C_IRQ4 (_ULCAST_(1) << 14) +#define C_IRQ5 (_ULCAST_(1) << 15) + +/* + * Bitfields in the R4xx0 cp0 status register + */ +#define ST0_IE 0x00000001 +#define ST0_EXL 0x00000002 +#define ST0_ERL 0x00000004 +#define ST0_KSU 0x00000018 +# define KSU_USER 0x00000010 +# define KSU_SUPERVISOR 0x00000008 +# define KSU_KERNEL 0x00000000 +#define ST0_UX 0x00000020 +#define ST0_SX 0x00000040 +#define ST0_KX 0x00000080 +#define ST0_DE 0x00010000 +#define ST0_CE 0x00020000 + +/* + * Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate + * cacheops in userspace. This bit exists only on RM7000 and RM9000 + * processors. + */ +#define ST0_CO 0x08000000 + +/* + * Bitfields in the R[23]000 cp0 status register. + */ +#define ST0_IEC 0x00000001 +#define ST0_KUC 0x00000002 +#define ST0_IEP 0x00000004 +#define ST0_KUP 0x00000008 +#define ST0_IEO 0x00000010 +#define ST0_KUO 0x00000020 +/* bits 6 & 7 are reserved on R[23]000 */ +#define ST0_ISC 0x00010000 +#define ST0_SWC 0x00020000 +#define ST0_CM 0x00080000 + +/* + * Bits specific to the R4640/R4650 + */ +#define ST0_UM (_ULCAST_(1) << 4) +#define ST0_IL (_ULCAST_(1) << 23) +#define ST0_DL (_ULCAST_(1) << 24) + +/* + * Enable the MIPS MDMX and DSP ASEs + */ +#define ST0_MX 0x01000000 + +/* + * Bitfields in the TX39 family CP0 Configuration Register 3 + */ +#define TX39_CONF_ICS_SHIFT 19 +#define TX39_CONF_ICS_MASK 0x00380000 +#define TX39_CONF_ICS_1KB 0x00000000 +#define TX39_CONF_ICS_2KB 0x00080000 +#define TX39_CONF_ICS_4KB 0x00100000 +#define TX39_CONF_ICS_8KB 0x00180000 +#define TX39_CONF_ICS_16KB 0x00200000 + +#define TX39_CONF_DCS_SHIFT 16 +#define TX39_CONF_DCS_MASK 0x00070000 +#define TX39_CONF_DCS_1KB 0x00000000 +#define TX39_CONF_DCS_2KB 0x00010000 +#define TX39_CONF_DCS_4KB 0x00020000 +#define TX39_CONF_DCS_8KB 0x00030000 +#define TX39_CONF_DCS_16KB 0x00040000 + +#define TX39_CONF_CWFON 0x00004000 +#define TX39_CONF_WBON 0x00002000 +#define TX39_CONF_RF_SHIFT 10 +#define TX39_CONF_RF_MASK 0x00000c00 +#define TX39_CONF_DOZE 0x00000200 +#define TX39_CONF_HALT 0x00000100 +#define TX39_CONF_LOCK 0x00000080 +#define TX39_CONF_ICE 0x00000020 +#define TX39_CONF_DCE 0x00000010 +#define TX39_CONF_IRSIZE_SHIFT 2 +#define TX39_CONF_IRSIZE_MASK 0x0000000c +#define TX39_CONF_DRSIZE_SHIFT 0 +#define TX39_CONF_DRSIZE_MASK 0x00000003 + +/* + * Status register bits available in all MIPS CPUs. + */ +#define ST0_IM 0x0000ff00 +#define STATUSB_IP0 8 +#define STATUSF_IP0 (_ULCAST_(1) << 8) +#define STATUSB_IP1 9 +#define STATUSF_IP1 (_ULCAST_(1) << 9) +#define STATUSB_IP2 10 +#define STATUSF_IP2 (_ULCAST_(1) << 10) +#define STATUSB_IP3 11 +#define STATUSF_IP3 (_ULCAST_(1) << 11) +#define STATUSB_IP4 12 +#define STATUSF_IP4 (_ULCAST_(1) << 12) +#define STATUSB_IP5 13 +#define STATUSF_IP5 (_ULCAST_(1) << 13) +#define STATUSB_IP6 14 +#define STATUSF_IP6 (_ULCAST_(1) << 14) +#define STATUSB_IP7 15 +#define STATUSF_IP7 (_ULCAST_(1) << 15) +#define STATUSB_IP8 0 +#define STATUSF_IP8 (_ULCAST_(1) << 0) +#define STATUSB_IP9 1 +#define STATUSF_IP9 (_ULCAST_(1) << 1) +#define STATUSB_IP10 2 +#define STATUSF_IP10 (_ULCAST_(1) << 2) +#define STATUSB_IP11 3 +#define STATUSF_IP11 (_ULCAST_(1) << 3) +#define STATUSB_IP12 4 +#define STATUSF_IP12 (_ULCAST_(1) << 4) +#define STATUSB_IP13 5 +#define STATUSF_IP13 (_ULCAST_(1) << 5) +#define STATUSB_IP14 6 +#define STATUSF_IP14 (_ULCAST_(1) << 6) +#define STATUSB_IP15 7 +#define STATUSF_IP15 (_ULCAST_(1) << 7) +#define ST0_CH 0x00040000 +#define ST0_SR 0x00100000 +#define ST0_TS 0x00200000 +#define ST0_BEV 0x00400000 +#define ST0_RE 0x02000000 +#define ST0_FR 0x04000000 +#define ST0_CU 0xf0000000 +#define ST0_CU0 0x10000000 +#define ST0_CU1 0x20000000 +#define ST0_CU2 0x40000000 +#define ST0_CU3 0x80000000 +#define ST0_XX 0x80000000 /* MIPS IV naming */ + +/* + * Bitfields and bit numbers in the coprocessor 0 cause register. + * + * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. + */ +#define CAUSEB_EXCCODE 2 +#define CAUSEF_EXCCODE (_ULCAST_(31) << 2) +#define CAUSEB_IP 8 +#define CAUSEF_IP (_ULCAST_(255) << 8) +#define CAUSEB_IP0 8 +#define CAUSEF_IP0 (_ULCAST_(1) << 8) +#define CAUSEB_IP1 9 +#define CAUSEF_IP1 (_ULCAST_(1) << 9) +#define CAUSEB_IP2 10 +#define CAUSEF_IP2 (_ULCAST_(1) << 10) +#define CAUSEB_IP3 11 +#define CAUSEF_IP3 (_ULCAST_(1) << 11) +#define CAUSEB_IP4 12 +#define CAUSEF_IP4 (_ULCAST_(1) << 12) +#define CAUSEB_IP5 13 +#define CAUSEF_IP5 (_ULCAST_(1) << 13) +#define CAUSEB_IP6 14 +#define CAUSEF_IP6 (_ULCAST_(1) << 14) +#define CAUSEB_IP7 15 +#define CAUSEF_IP7 (_ULCAST_(1) << 15) +#define CAUSEB_IV 23 +#define CAUSEF_IV (_ULCAST_(1) << 23) +#define CAUSEB_CE 28 +#define CAUSEF_CE (_ULCAST_(3) << 28) +#define CAUSEB_BD 31 +#define CAUSEF_BD (_ULCAST_(1) << 31) + +/* + * Bits in the coprocessor 0 config register. + */ +/* Generic bits. */ +#define CONF_CM_CACHABLE_NO_WA 0 +#define CONF_CM_CACHABLE_WA 1 +#define CONF_CM_UNCACHED 2 +#define CONF_CM_CACHABLE_NONCOHERENT 3 +#define CONF_CM_CACHABLE_CE 4 +#define CONF_CM_CACHABLE_COW 5 +#define CONF_CM_CACHABLE_CUW 6 +#define CONF_CM_CACHABLE_ACCELERATED 7 +#define CONF_CM_CMASK 7 +#define CONF_BE (_ULCAST_(1) << 15) + +/* Bits common to various processors. */ +#define CONF_CU (_ULCAST_(1) << 3) +#define CONF_DB (_ULCAST_(1) << 4) +#define CONF_IB (_ULCAST_(1) << 5) +#define CONF_DC (_ULCAST_(7) << 6) +#define CONF_IC (_ULCAST_(7) << 9) +#define CONF_EB (_ULCAST_(1) << 13) +#define CONF_EM (_ULCAST_(1) << 14) +#define CONF_SM (_ULCAST_(1) << 16) +#define CONF_SC (_ULCAST_(1) << 17) +#define CONF_EW (_ULCAST_(3) << 18) +#define CONF_EP (_ULCAST_(15)<< 24) +#define CONF_EC (_ULCAST_(7) << 28) +#define CONF_CM (_ULCAST_(1) << 31) + +/* Bits specific to the R4xx0. */ +#define R4K_CONF_SW (_ULCAST_(1) << 20) +#define R4K_CONF_SS (_ULCAST_(1) << 21) +#define R4K_CONF_SB (_ULCAST_(3) << 22) + +/* Bits specific to the R5000. */ +#define R5K_CONF_SE (_ULCAST_(1) << 12) +#define R5K_CONF_SS (_ULCAST_(3) << 20) + +/* Bits specific to the RM7000. */ +#define RM7K_CONF_SE (_ULCAST_(1) << 3) +#define RM7K_CONF_TE (_ULCAST_(1) << 12) +#define RM7K_CONF_CLK (_ULCAST_(1) << 16) +#define RM7K_CONF_TC (_ULCAST_(1) << 17) +#define RM7K_CONF_SI (_ULCAST_(3) << 20) +#define RM7K_CONF_SC (_ULCAST_(1) << 31) + +/* Bits specific to the R10000. */ +#define R10K_CONF_DN (_ULCAST_(3) << 3) +#define R10K_CONF_CT (_ULCAST_(1) << 5) +#define R10K_CONF_PE (_ULCAST_(1) << 6) +#define R10K_CONF_PM (_ULCAST_(3) << 7) +#define R10K_CONF_EC (_ULCAST_(15)<< 9) +#define R10K_CONF_SB (_ULCAST_(1) << 13) +#define R10K_CONF_SK (_ULCAST_(1) << 14) +#define R10K_CONF_SS (_ULCAST_(7) << 16) +#define R10K_CONF_SC (_ULCAST_(7) << 19) +#define R10K_CONF_DC (_ULCAST_(7) << 26) +#define R10K_CONF_IC (_ULCAST_(7) << 29) + +/* Bits specific to the VR41xx. */ +#define VR41_CONF_CS (_ULCAST_(1) << 12) +#define VR41_CONF_P4K (_ULCAST_(1) << 13) +#define VR41_CONF_BP (_ULCAST_(1) << 16) +#define VR41_CONF_M16 (_ULCAST_(1) << 20) +#define VR41_CONF_AD (_ULCAST_(1) << 23) + +/* Bits specific to the R30xx. */ +#define R30XX_CONF_FDM (_ULCAST_(1) << 19) +#define R30XX_CONF_REV (_ULCAST_(1) << 22) +#define R30XX_CONF_AC (_ULCAST_(1) << 23) +#define R30XX_CONF_RF (_ULCAST_(1) << 24) +#define R30XX_CONF_HALT (_ULCAST_(1) << 25) +#define R30XX_CONF_FPINT (_ULCAST_(7) << 26) +#define R30XX_CONF_DBR (_ULCAST_(1) << 29) +#define R30XX_CONF_SB (_ULCAST_(1) << 30) +#define R30XX_CONF_LOCK (_ULCAST_(1) << 31) + +/* Bits specific to the TX49. */ +#define TX49_CONF_DC (_ULCAST_(1) << 16) +#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */ +#define TX49_CONF_HALT (_ULCAST_(1) << 18) +#define TX49_CONF_CWFON (_ULCAST_(1) << 27) + +/* Bits specific to the MIPS32/64 PRA. */ +#define MIPS_CONF_MT (_ULCAST_(7) << 7) +#define MIPS_CONF_AR (_ULCAST_(7) << 10) +#define MIPS_CONF_AT (_ULCAST_(3) << 13) +#define MIPS_CONF_M (_ULCAST_(1) << 31) + +/* + * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above. + */ +#define MIPS_CONF1_FP (_ULCAST_(1) << 0) +#define MIPS_CONF1_EP (_ULCAST_(1) << 1) +#define MIPS_CONF1_CA (_ULCAST_(1) << 2) +#define MIPS_CONF1_WR (_ULCAST_(1) << 3) +#define MIPS_CONF1_PC (_ULCAST_(1) << 4) +#define MIPS_CONF1_MD (_ULCAST_(1) << 5) +#define MIPS_CONF1_C2 (_ULCAST_(1) << 6) +#define MIPS_CONF1_DA (_ULCAST_(7) << 7) +#define MIPS_CONF1_DL (_ULCAST_(7) << 10) +#define MIPS_CONF1_DS (_ULCAST_(7) << 13) +#define MIPS_CONF1_IA (_ULCAST_(7) << 16) +#define MIPS_CONF1_IL (_ULCAST_(7) << 19) +#define MIPS_CONF1_IS (_ULCAST_(7) << 22) +#define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25) + +#define MIPS_CONF2_SA (_ULCAST_(15)<< 0) +#define MIPS_CONF2_SL (_ULCAST_(15)<< 4) +#define MIPS_CONF2_SS (_ULCAST_(15)<< 8) +#define MIPS_CONF2_SU (_ULCAST_(15)<< 12) +#define MIPS_CONF2_TA (_ULCAST_(15)<< 16) +#define MIPS_CONF2_TL (_ULCAST_(15)<< 20) +#define MIPS_CONF2_TS (_ULCAST_(15)<< 24) +#define MIPS_CONF2_TU (_ULCAST_(7) << 28) + +#define MIPS_CONF3_TL (_ULCAST_(1) << 0) +#define MIPS_CONF3_SM (_ULCAST_(1) << 1) +#define MIPS_CONF3_MT (_ULCAST_(1) << 2) +#define MIPS_CONF3_SP (_ULCAST_(1) << 4) +#define MIPS_CONF3_VINT (_ULCAST_(1) << 5) +#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) +#define MIPS_CONF3_LPA (_ULCAST_(1) << 7) +#define MIPS_CONF3_DSP (_ULCAST_(1) << 10) +#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) + +#define MIPS_CONF7_WII (_ULCAST_(1) << 31) + +#define MIPS_CONF7_RPS (_ULCAST_(1) << 2) + + +/* + * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. + */ +#define MIPS_FPIR_S (_ULCAST_(1) << 16) +#define MIPS_FPIR_D (_ULCAST_(1) << 17) +#define MIPS_FPIR_PS (_ULCAST_(1) << 18) +#define MIPS_FPIR_3D (_ULCAST_(1) << 19) +#define MIPS_FPIR_W (_ULCAST_(1) << 20) +#define MIPS_FPIR_L (_ULCAST_(1) << 21) +#define MIPS_FPIR_F64 (_ULCAST_(1) << 22) + +#ifndef __ASSEMBLY__ + +/* + * Functions to access the R10000 performance counters. These are basically + * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit + * performance counter number encoded into bits 1 ... 5 of the instruction. + * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware + * disassembler these will look like an access to sel 0 or 1. + */ +#define read_r10k_perf_cntr(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) + +#define write_r10k_perf_cntr(counter,val) \ +do { \ + __asm__ __volatile__( \ + "mtpc\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + +#define read_r10k_perf_event(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) + +#define write_r10k_perf_cntl(counter,val) \ +do { \ + __asm__ __volatile__( \ + "mtps\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + + +/* + * Macros to access the system control coprocessor + */ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c0_register(source, sel) \ +({ unsigned long long __res; \ + if (sizeof(unsigned long) == 4) \ + __res = __read_64bit_c0_split(source, sel); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0, " #source "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __write_64bit_c0_register(register, sel, value) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_64bit_c0_split(register, sel, value); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%z0, " #register "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + (unsigned long) __read_32bit_c0_register(reg, sel) : \ + (unsigned long) __read_64bit_c0_register(reg, sel)) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_32bit_c0_register(reg, sel, val); \ + else \ + __write_64bit_c0_register(reg, sel, val); \ +} while (0) + +/* + * On RM7000/RM9000 these are uses to access cop0 set 1 registers + */ +#define __read_32bit_c0_ctrl_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "cfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_ctrl_register(register, value) \ +do { \ + __asm__ __volatile__( \ + "ctc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#define __read_64bit_c0_split(source, sel) \ +({ \ + unsigned long long __val; \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsra\t%M0, %M0, 32\n\t" \ + "dsra\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (__val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsra\t%M0, %M0, 32\n\t" \ + "dsra\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (__val)); \ + local_irq_restore(__flags); \ + \ + __val; \ +}) + +#define __write_64bit_c0_split(source, sel, val) \ +do { \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + local_irq_restore(__flags); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_random() __read_32bit_c0_register($1, 0) +#define write_c0_random(val) __write_32bit_c0_register($1, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ +#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) + +#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ +#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ +#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) + +#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ +#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#ifdef CONFIG_MIPS_MT_SMTC +#define write_c0_status(val) \ +do { \ + __write_32bit_c0_register($12, 0, val); \ + __ehb(); \ +} while (0) +#else +/* + * Legacy non-SMTC code, which may be hazardous + * but which might not support EHB + */ +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) +#endif /* CONFIG_MIPS_MT_SMTC */ + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define read_c0_config4() __read_32bit_c0_register($16, 4) +#define read_c0_config5() __read_32bit_c0_register($16, 5) +#define read_c0_config6() __read_32bit_c0_register($16, 6) +#define read_c0_config7() __read_32bit_c0_register($16, 7) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) +#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val) +#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val) +#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) +#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20) +#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +/* RM9000 PerfControl performance counter control register */ +#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0) +#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val) + +#define read_c0_diag() __read_32bit_c0_register($22, 0) +#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) + +#define read_c0_diag1() __read_32bit_c0_register($22, 1) +#define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val) + +#define read_c0_diag2() __read_32bit_c0_register($22, 2) +#define write_c0_diag2(val) __write_32bit_c0_register($22, 2, val) + +#define read_c0_diag3() __read_32bit_c0_register($22, 3) +#define write_c0_diag3(val) __write_32bit_c0_register($22, 3, val) + +#define read_c0_diag4() __read_32bit_c0_register($22, 4) +#define write_c0_diag4(val) __write_32bit_c0_register($22, 4, val) + +#define read_c0_diag5() __read_32bit_c0_register($22, 5) +#define write_c0_diag5(val) __write_32bit_c0_register($22, 5, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_perfctrl0() __read_32bit_c0_register($25, 0) +#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) +#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) +#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) +#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) +#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) +#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) +#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) +#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) +#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) +#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) +#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) +#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) +#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) +#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) +#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) + +/* RM9000 PerfCount performance counter register */ +#define read_c0_perfcount() __read_64bit_c0_register($25, 0) +#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* MIPSR2 */ +#define read_c0_hwrena() __read_32bit_c0_register($7, 0) +#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_intctl() __read_32bit_c0_register($12, 1) +#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val) + +#define read_c0_srsctl() __read_32bit_c0_register($12, 2) +#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val) + +#define read_c0_srsmap() __read_32bit_c0_register($12, 3) +#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val) + +#define read_c0_ebase() __read_32bit_c0_register($15, 1) +#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) + + +/* Cavium OCTEON (cnMIPS) */ +#define read_c0_cvmcount() __read_ulong_c0_register($9, 6) +#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) + +#define read_c0_cvmctl() __read_64bit_c0_register($9, 7) +#define write_c0_cvmctl(val) __write_64bit_c0_register($9, 7, val) + +#define read_c0_cvmmemctl() __read_64bit_c0_register($11, 7) +#define write_c0_cvmmemctl(val) __write_64bit_c0_register($11, 7, val) +/* + * The cacheerr registers are not standardized. On OCTEON, they are + * 64 bits wide. + */ +#define read_octeon_c0_icacheerr() __read_64bit_c0_register($27, 0) +#define write_octeon_c0_icacheerr(val) __write_64bit_c0_register($27, 0, val) + +#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1) +#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + /* gas fails to assemble cfc1 for some archs (octeon).*/ \ + ".set\tmips1\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +#define rddsp(mask) \ +({ \ + unsigned int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # rddsp $1, %x1 \n" \ + " .word 0x7c000cb8 | (%x1 << 16) \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__res) \ + : "i" (mask)); \ + __res; \ +}) + +#define wrdsp(val, mask) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # wrdsp $1, %x1 \n" \ + " .word 0x7c2004f8 | (%x1 << 11) \n" \ + " .set pop \n" \ + : \ + : "r" (val), "i" (mask)); \ +} while (0) + +#if 0 /* Need DSP ASE capable assembler ... */ +#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) +#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) +#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) +#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;}) + +#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;}) +#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;}) +#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;}) +#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;}) + +#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x)) +#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x)) +#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x)) +#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x)) + +#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x)) +#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x)) +#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x)) +#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x)) + +#else + +#define mfhi0() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac0 \n" \ + " .word 0x00000810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi1() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac1 \n" \ + " .word 0x00200810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi2() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac2 \n" \ + " .word 0x00400810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi3() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac3 \n" \ + " .word 0x00600810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo0() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac0 \n" \ + " .word 0x00000812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo1() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac1 \n" \ + " .word 0x00200812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo2() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac2 \n" \ + " .word 0x00400812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo3() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac3 \n" \ + " .word 0x00600812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mthi0(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac0 \n" \ + " .word 0x00200011 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi1(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac1 \n" \ + " .word 0x00200811 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi2(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac2 \n" \ + " .word 0x00201011 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi3(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac3 \n" \ + " .word 0x00201811 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo0(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac0 \n" \ + " .word 0x00200013 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo1(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac1 \n" \ + " .word 0x00200813 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo2(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac2 \n" \ + " .word 0x00201013 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo3(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac3 \n" \ + " .word 0x00201813 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#endif + +/* + * TLB operations. + * + * It is responsibility of the caller to take care of any TLB hazards. + */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ +#if MIPS34K_MISSED_ITLB_WAR + int res = 0; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41610001 # dvpe $1 \n" + " move %0, $1 \n" + " ehb \n" + " .set pop \n" + : "=r" (res)); + + instruction_hazard(); +#endif + + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); + +#if MIPS34K_MISSED_ITLB_WAR + if ((res & _ULCAST_(1))) + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41600021 # evpe \n" + " ehb \n" + " .set pop \n"); +#endif +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* + * Manipulate bits in a c0 register. + */ +#ifndef CONFIG_MIPS_MT_SMTC +/* + * SMTC Linux requires shutting-down microthread scheduling + * during CP0 register read-modify-write sequences. + */ +#define __BUILD_SET_C0(name) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res, new; \ + \ + res = read_c0_##name(); \ + new = res | set; \ + write_c0_##name(new); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res, new; \ + \ + res = read_c0_##name(); \ + new = res & ~clear; \ + write_c0_##name(new); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int val) \ +{ \ + unsigned int res, new; \ + \ + res = read_c0_##name(); \ + new = res & ~change; \ + new |= (val & change); \ + write_c0_##name(new); \ + \ + return res; \ +} + +#else /* SMTC versions that manage MT scheduling */ + +#include + +/* + * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with + * header file recursion. + */ +static inline unsigned int __dmt(void) +{ + int res; + + __asm__ __volatile__( + " .set push \n" + " .set mips32r2 \n" + " .set noat \n" + " .word 0x41610BC1 # dmt $1 \n" + " ehb \n" + " move %0, $1 \n" + " .set pop \n" + : "=r" (res)); + + instruction_hazard(); + + return res; +} + +#define __VPECONTROL_TE_SHIFT 15 +#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT) + +#define __EMT_ENABLE __VPECONTROL_TE + +static inline void __emt(unsigned int previous) +{ + if ((previous & __EMT_ENABLE)) + __asm__ __volatile__( + " .set mips32r2 \n" + " .word 0x41600be1 # emt \n" + " ehb \n" + " .set mips0 \n"); +} + +static inline void __ehb(void) +{ + __asm__ __volatile__( + " .set mips32r2 \n" + " ehb \n" " .set mips0 \n"); +} + +/* + * Note that local_irq_save/restore affect TC-specific IXMT state, + * not Status.IE as in non-SMTC kernel. + */ + +#define __BUILD_SET_C0(name) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + unsigned int new; \ + unsigned int omt; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + omt = __dmt(); \ + res = read_c0_##name(); \ + new = res | set; \ + write_c0_##name(new); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + unsigned int new; \ + unsigned int omt; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + omt = __dmt(); \ + res = read_c0_##name(); \ + new = res & ~clear; \ + write_c0_##name(new); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int newbits) \ +{ \ + unsigned int res; \ + unsigned int new; \ + unsigned int omt; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + \ + omt = __dmt(); \ + res = read_c0_##name(); \ + new = res & ~change; \ + new |= (newbits & change); \ + write_c0_##name(new); \ + __emt(omt); \ + local_irq_restore(flags); \ + \ + return res; \ +} +#endif + +__BUILD_SET_C0(status) +__BUILD_SET_C0(cause) +__BUILD_SET_C0(config) +__BUILD_SET_C0(intcontrol) +__BUILD_SET_C0(intctl) +__BUILD_SET_C0(srsmap) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_MIPSREGS_H */ diff --git a/resources/project/include/asm/page.h b/resources/project/include/asm/page.h new file mode 100644 index 0000000..6064120 --- /dev/null +++ b/resources/project/include/asm/page.h @@ -0,0 +1,10 @@ +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H +#include + +#ifdef CONFIG_PAGE_SIZE_16KB +#define PAGE_SHIFT 14 +#endif + +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#endif /* _ASM_PAGE_H */ diff --git a/resources/project/include/asm/r4kcache.h b/resources/project/include/asm/r4kcache.h new file mode 100644 index 0000000..9c00f94 --- /dev/null +++ b/resources/project/include/asm/r4kcache.h @@ -0,0 +1,446 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Inline assembly cache operations. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org) + */ +#ifndef _ASM_R4KCACHE_H +#define _ASM_R4KCACHE_H + +#include +#include +#include +#include +#include +//#include +//#include +#define icache_waysize 0x1000 +#define icache_waybit 12 +#define icache_ways 4 +#define dcache_waysize 0x1000 +#define dcache_waybit 12 +#define dcache_ways 4 +#define dcache_line_size 32 +#define icache_line_size 32 +#define scache_line_size 32 + + +/* + * This macro return a properly sign-extended address suitable as base address + * for indexed cache operations. Two issues here: + * + * - The MIPS32 and MIPS64 specs permit an implementation to directly derive + * the index bits from the virtual address. This breaks with tradition + * set by the R4000. To keep unpleasant surprises from happening we pick + * an address in KSEG0 / CKSEG0. + * - We need a properly sign extended address for 64-bit code. To get away + * without ifdefs we let the compiler do it by a type cast. + */ +#define INDEX_BASE CKSEG0 + +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +#ifdef CONFIG_MIPS_MT +/* + * Temporary hacks for SMTC debug. Optionally force single-threaded + * execution during I-cache flushes. + */ + +#define PROTECT_CACHE_FLUSHES 1 + +#ifdef PROTECT_CACHE_FLUSHES + +extern int mt_protiflush; +extern int mt_protdflush; +extern void mt_cflush_lockdown(void); +extern void mt_cflush_release(void); + +#define BEGIN_MT_IPROT \ + unsigned long flags = 0; \ + unsigned long mtflags = 0; \ + if(mt_protiflush) { \ + local_irq_save(flags); \ + ehb(); \ + mtflags = dvpe(); \ + mt_cflush_lockdown(); \ + } + +#define END_MT_IPROT \ + if(mt_protiflush) { \ + mt_cflush_release(); \ + evpe(mtflags); \ + local_irq_restore(flags); \ + } + +#define BEGIN_MT_DPROT \ + unsigned long flags = 0; \ + unsigned long mtflags = 0; \ + if(mt_protdflush) { \ + local_irq_save(flags); \ + ehb(); \ + mtflags = dvpe(); \ + mt_cflush_lockdown(); \ + } + +#define END_MT_DPROT \ + if(mt_protdflush) { \ + mt_cflush_release(); \ + evpe(mtflags); \ + local_irq_restore(flags); \ + } + +#else + +#define BEGIN_MT_IPROT +#define BEGIN_MT_DPROT +#define END_MT_IPROT +#define END_MT_DPROT + +#endif /* PROTECT_CACHE_FLUSHES */ + +#define __iflush_prologue \ + unsigned long redundance; \ + extern int mt_n_iflushes; \ + BEGIN_MT_IPROT \ + for (redundance = 0; redundance < mt_n_iflushes; redundance++) { + +#define __iflush_epilogue \ + END_MT_IPROT \ + } + +#define __dflush_prologue \ + unsigned long redundance; \ + extern int mt_n_dflushes; \ + BEGIN_MT_DPROT \ + for (redundance = 0; redundance < mt_n_dflushes; redundance++) { + +#define __dflush_epilogue \ + END_MT_DPROT \ + } + +#define __inv_dflush_prologue __dflush_prologue +#define __inv_dflush_epilogue __dflush_epilogue +#define __sflush_prologue { +#define __sflush_epilogue } +#define __inv_sflush_prologue __sflush_prologue +#define __inv_sflush_epilogue __sflush_epilogue + +#else /* CONFIG_MIPS_MT */ + +#define __iflush_prologue { +#define __iflush_epilogue } +#define __dflush_prologue { +#define __dflush_epilogue } +#define __inv_dflush_prologue { +#define __inv_dflush_epilogue } +#define __sflush_prologue { +#define __sflush_epilogue } +#define __inv_sflush_prologue { +#define __inv_sflush_epilogue } + +#endif /* CONFIG_MIPS_MT */ + +static inline void flush_icache_line_indexed(unsigned long addr) +{ + __iflush_prologue + cache_op(Index_Invalidate_I, addr); + __iflush_epilogue +} + +static inline void flush_dcache_line_indexed(unsigned long addr) +{ + __dflush_prologue + cache_op(Index_Writeback_Inv_D, addr); + __dflush_epilogue +} + +static inline void flush_scache_line_indexed(unsigned long addr) +{ + cache_op(Index_Writeback_Inv_SD, addr); +} + +static inline void flush_icache_line(unsigned long addr) +{ + __iflush_prologue + cache_op(Hit_Invalidate_I, addr); + __iflush_epilogue +} + +static inline void flush_dcache_line(unsigned long addr) +{ + __dflush_prologue + cache_op(Hit_Writeback_Inv_D, addr); + __dflush_epilogue +} + +static inline void invalidate_dcache_line(unsigned long addr) +{ + __dflush_prologue + cache_op(Hit_Invalidate_D, addr); + __dflush_epilogue +} + +static inline void invalidate_scache_line(unsigned long addr) +{ + cache_op(Hit_Invalidate_SD, addr); +} + +static inline void flush_scache_line(unsigned long addr) +{ + cache_op(Hit_Writeback_Inv_SD, addr); +} + +#define protected_cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + "1: cache %0, (%1) \n" \ + "2: .set pop \n" \ + : \ + : "i" (op), "r" (addr)) + +/* + * The next two are for badland addresses like signal trampolines. + */ +static inline void protected_flush_icache_line(unsigned long addr) +{ + protected_cache_op(Hit_Invalidate_I, addr); +} + +/* + * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D + * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style + * caches. We're talking about one cacheline unnecessarily getting invalidated + * here so the penalty isn't overly hard. + */ +static inline void protected_writeback_dcache_line(unsigned long addr) +{ + protected_cache_op(Hit_Writeback_Inv_D, addr); +} + +static inline void protected_writeback_scache_line(unsigned long addr) +{ + protected_cache_op(Hit_Writeback_Inv_SD, addr); +} + +/* + * This one is RM7000-specific + */ +static inline void invalidate_tcache_page(unsigned long addr) +{ + cache_op(Page_Invalidate_T, addr); +} + +#define cache16_unroll32(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \ + " cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \ + " cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \ + " cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \ + " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \ + " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \ + " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \ + " cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \ + " cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \ + " cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \ + " cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \ + " cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \ + " cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +#define cache32_unroll32(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \ + " cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \ + " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \ + " cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \ + " cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \ + " cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \ + " cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \ + " cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \ + " cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \ + " cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \ + " cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +#define cache64_unroll32(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x0c0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x140(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x1c0(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x240(%0) \n" \ + " cache %1, 0x280(%0); cache %1, 0x2c0(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x340(%0) \n" \ + " cache %1, 0x380(%0); cache %1, 0x3c0(%0) \n" \ + " cache %1, 0x400(%0); cache %1, 0x440(%0) \n" \ + " cache %1, 0x480(%0); cache %1, 0x4c0(%0) \n" \ + " cache %1, 0x500(%0); cache %1, 0x540(%0) \n" \ + " cache %1, 0x580(%0); cache %1, 0x5c0(%0) \n" \ + " cache %1, 0x600(%0); cache %1, 0x640(%0) \n" \ + " cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \ + " cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \ + " cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +#define cache128_unroll32(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x080(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x180(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x280(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x380(%0) \n" \ + " cache %1, 0x400(%0); cache %1, 0x480(%0) \n" \ + " cache %1, 0x500(%0); cache %1, 0x580(%0) \n" \ + " cache %1, 0x600(%0); cache %1, 0x680(%0) \n" \ + " cache %1, 0x700(%0); cache %1, 0x780(%0) \n" \ + " cache %1, 0x800(%0); cache %1, 0x880(%0) \n" \ + " cache %1, 0x900(%0); cache %1, 0x980(%0) \n" \ + " cache %1, 0xa00(%0); cache %1, 0xa80(%0) \n" \ + " cache %1, 0xb00(%0); cache %1, 0xb80(%0) \n" \ + " cache %1, 0xc00(%0); cache %1, 0xc80(%0) \n" \ + " cache %1, 0xd00(%0); cache %1, 0xd80(%0) \n" \ + " cache %1, 0xe00(%0); cache %1, 0xe80(%0) \n" \ + " cache %1, 0xf00(%0); cache %1, 0xf80(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ +#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \ +static inline void blast_##pfx##cache##lsize(void) \ +{ \ + unsigned long start = INDEX_BASE; \ + unsigned long end = start + desc##_##waysize; \ + unsigned long ws_inc = 1UL << desc##_##waybit; \ + unsigned long ws_end = desc##_##ways << \ + desc##_##waybit; \ + unsigned long ws, addr; \ + \ + __##pfx##flush_prologue \ + \ + for (ws = 0; ws < ws_end; ws += ws_inc) \ + for (addr = start; addr < end; addr += lsize * 32) \ + cache##lsize##_unroll32(addr|ws, indexop); \ + \ + __##pfx##flush_epilogue \ +} \ + \ +static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ +{ \ + unsigned long start = page; \ + unsigned long end = page + PAGE_SIZE; \ + \ + __##pfx##flush_prologue \ + \ + do { \ + cache##lsize##_unroll32(start, hitop); \ + start += lsize * 32; \ + } while (start < end); \ + \ + __##pfx##flush_epilogue \ +} \ + \ +static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ +{ \ + unsigned long indexmask = desc##_##waysize - 1; \ + unsigned long start = INDEX_BASE + (page & indexmask); \ + unsigned long end = start + PAGE_SIZE; \ + unsigned long ws_inc = 1UL << desc##_##waybit; \ + unsigned long ws_end = desc##_##ways << \ + desc##_##waybit; \ + unsigned long ws, addr; \ + \ + __##pfx##flush_prologue \ + \ + for (ws = 0; ws < ws_end; ws += ws_inc) \ + for (addr = start; addr < end; addr += lsize * 32) \ + cache##lsize##_unroll32(addr|ws, indexop); \ + \ + __##pfx##flush_epilogue \ +} + +__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) +__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16) +__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32) +__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32) +__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64) +__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) + +__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16) +__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32) + +/* build blast_xxx_range, protected_blast_xxx_range */ +#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ +static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ + unsigned long end) \ +{ \ + unsigned long lsize = desc##_line_size; \ + unsigned long addr = start & ~(lsize - 1); \ + unsigned long aend = (end - 1) & ~(lsize - 1); \ + \ + __##pfx##flush_prologue \ + \ + while (1) { \ + prot##cache_op(hitop, addr); \ + if (addr == aend) \ + break; \ + addr += lsize; \ + } \ + \ + __##pfx##flush_epilogue \ +} + +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) +__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) +/* blast_inv_dcache_range */ +__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) +__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, ) + +#endif /* _ASM_R4KCACHE_H */ diff --git a/resources/project/include/asm/regdef.h b/resources/project/include/asm/regdef.h new file mode 100644 index 0000000..5bdf816 --- /dev/null +++ b/resources/project/include/asm/regdef.h @@ -0,0 +1,113 @@ +/* $OpenBSD: regdef.h,v 1.3 1999/01/27 04:46:06 imp Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. This file is derived from the MIPS RISC + * Architecture book by Gerry Kane. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)regdef.h 8.1 (Berkeley) 6/10/93 + */ +#ifndef _MIPS_REGDEF_H_ +#define _MIPS_REGDEF_H_ + +#define zero $0 /* always zero */ +#define AT $at /* assembler temp */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* temp registers (not saved across subroutine calls) */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* saved across subroutine calls (callee saved) */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* two more temp registers */ +#define t9 $25 +#define k0 $26 /* kernel temporary */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define s8 $30 /* one more callee saved */ +#define ra $31 /* return address */ +#define fp $30 + +#define c0_index $0 +#define c0_random $1 +#define c0_entrylo0 $2 +#define c0_entrylo1 $3 +#define c0_conf $3 +#define c0_context $4 +#define c0_pagemask $5 +#define c0_wired $6 +#define c0_info $7 +#define c0_badvaddr $8 +#define c0_count $9 +#define c0_entryhi $10 +#define c0_compare $11 +#define c0_status $12 +#define c0_cause $13 +#define c0_epc $14 +#define c0_prid $15 +#define c0_config $16 +#define c0_lladdr $17 +#define c0_watchlo $18 +#define c0_watchhi $19 +#define c0_xcontext $20 +#define c0_framemask $21 +#define c0_diagnostic $22 +#define c0_debug $23 +#define c0_depc $24 +#define c0_performance $25 +#define c0_ecc $26 +#define c0_cacheerr $27 +#define c0_taglo $28 +#define c0_taghi $29 +#define c0_errorepc $30 +#define c0_desave $31 + + +#endif /* !_MIPS_REGDEF_H_ */ diff --git a/resources/project/include/cmdline.h b/resources/project/include/cmdline.h new file mode 100644 index 0000000..ed4fe66 --- /dev/null +++ b/resources/project/include/cmdline.h @@ -0,0 +1,14 @@ +#ifndef __CMDLINE_H__ +#define __CMDLINE_H__ +typedef struct cmd_struct { + const char *cmdname; + int (*func)(int, void *[]); + int repeat; + const char *usage; + const char *expression; +} cmdline_t; + +#define V_NUM 8 //the number of argv +#define V_LEN 15 //the length of argv +#define CMD_BUFF 64 +#endif diff --git a/resources/project/include/common.h b/resources/project/include/common.h new file mode 100644 index 0000000..f929942 --- /dev/null +++ b/resources/project/include/common.h @@ -0,0 +1,180 @@ +#ifndef COMMON_H +#define COMMON_H + +#define SERIAL 0xffffffffff2001e0 + +#ifndef __ASSEMBLER__ +typedef void * va_list; +#if __GNUC__<3 || (__GNUC__==3 && __GNUC_MINOR__<3) +#define va_start(ap,fmt) ap=((void *)&fmt)+1; +#else +#define va_start __builtin_va_start +#endif +#define va_arg __builtin_va_arg +#define va_end __builtin_va_end +#define __P(x) x +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned int uint32_t; +typedef unsigned int size_t; + +#define isdigit(c) (c>='0' && c<='9') +#define FMT_RJUST 0 +#define FMT_LJUST 1 +#define FMT_RJUST0 2 +#define FMT_CENTER 3 + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ +#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) + +#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ +#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ +#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) + +#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ +#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) + +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define read_c0_config4() __read_32bit_c0_register($16, 4) +#define read_c0_config5() __read_32bit_c0_register($16, 5) +#define read_c0_config6() __read_32bit_c0_register($16, 6) +#define read_c0_config7() __read_32bit_c0_register($16, 7) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) +#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val) +#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val) +#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) +#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) +#endif + +#endif diff --git a/resources/project/include/const.h b/resources/project/include/const.h new file mode 100644 index 0000000..c22c707 --- /dev/null +++ b/resources/project/include/const.h @@ -0,0 +1,24 @@ +/* const.h: Macros for dealing with constants. */ + +#ifndef _LINUX_CONST_H +#define _LINUX_CONST_H + +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specifiers unilaterally. We + * use the following macros to deal with this. + * + * Similarly, _AT() will cast an expression with a type in C, but + * leave it unchanged in asm. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#endif /* !(_LINUX_CONST_H) */ diff --git a/resources/project/include/cpu.h b/resources/project/include/cpu.h new file mode 100644 index 0000000..f60e8fe --- /dev/null +++ b/resources/project/include/cpu.h @@ -0,0 +1,5 @@ +#ifndef __CPU_H_ +#define __CPU_H_ +#define SR_BOOT_EXC_VEC 0x00400000 +#define PG_SIZE_4K 0x00000000 +#endif diff --git a/resources/project/include/cpu_cde.h b/resources/project/include/cpu_cde.h new file mode 100644 index 0000000..d229e47 --- /dev/null +++ b/resources/project/include/cpu_cde.h @@ -0,0 +1,105 @@ +//soc confreg +#define CONFREG_NULL 0xbfaf8ffc + +#define CONFREG_CR0 0xbfaf8000 +#define CONFREG_CR1 0xbfaf8004 +#define CONFREG_CR2 0xbfaf8008 +#define CONFREG_CR3 0xbfaf800c +#define CONFREG_CR4 0xbfaf8010 +#define CONFREG_CR5 0xbfaf8014 +#define CONFREG_CR6 0xbfaf8018 +#define CONFREG_CR7 0xbfaf801c + +#define UART_ADDR 0xbfaffff0 +#define SIMU_FLAG_ADDR 0xbfaffff4 +#define OPEN_TRACE_ADDR 0xbfaffff8 +#define NUM_MONITOR_ADDR 0xbfaffffc +#define LED_ADDR 0xbfaff000 +#define LED_RG0_ADDR 0xbfaff004 +#define LED_RG1_ADDR 0xbfaff008 +#define NUM_ADDR 0xbfaff010 +#define SWITCH_ADDR 0xbfaff020 +#define BTN_KEY_ADDR 0xbfaff024 +#define BTN_STEP_ADDR 0xbfaff028 +#define TIMER_ADDR 0xbfafe000 + +#define SOC_LED (* (volatile unsigned *) LED_ADDR ) +#define SOC_LED_RG0 (* (volatile unsigned *) LED_RG0_ADDR ) +#define SOC_LED_RG1 (* (volatile unsigned *) LED_RG1_ADDR ) +#define SOC_NUM (* (volatile unsigned *) NUM_ADDR ) +#define SOC_SWITCHE (* (volatile unsigned *) SWITCH_ADDR ) +#define SOC_BTN_KEY (* (volatile unsigned *) BTN_KEY_ADDR ) +#define SOC_BTN_STEP (* (volatile unsigned *) BTN_STEP_ADDR ) +#define SOC_TIMER (* (volatile unsigned *) TIMER_ADDR ) +//#define disable_trace_cmp *((volatile int *)OPEN_TRACE_ADDR) = 0; \ +// *((volatile int *)CONFREG_NULL ) = 0; \ +// *((volatile int *)CONFREG_NULL ) = 0 +//#define enable_trace_cmp *((volatile int *)OPEN_TRACE_ADDR) = 1; \ +// *((volatile int *)CONFREG_NULL ) = 0; \ + *((volatile int *)CONFREG_NULL ) = 0 +#define trace_cmp_flag (*((volatile int *)OPEN_TRACE_ADDR)) +#define disable_trace_cmp asm volatile( \ + ".set noreorder;" \ + "lui $25,0xbfb0\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $0,-0x8($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "lw $0,-0x7004($25)\n\t" \ + "lw $25,-0x8($25)\n\t" \ + ".set reorder" \ + :::"$25" \ + ) +#define disable_trace_cmp_s .set noreorder; \ + lui k1,0xbfb0; \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + sw $0,-0x8(k1); \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + lw $0,-0x7004(k1); \ + lw k1,-0x8(k1); \ + .set reorder; \ + +#define disable_num_monitor_s .set noreorder; \ + lui k1,0xbfb0; \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + sw $0,-0x4(k1); \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + lw $0,-0x7004(k1); \ + lw k1,-0x4(k1); \ + .set reorder; \ + +#define enable_trace_cmp asm volatile( \ + ".set noreorder;" \ + "lui $25,0xbfb0\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $25,-8($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "sw $0,-0x7004($25)\n\t" \ + "lw $0,-0x7004($25)\n\t" \ + "lw $25,-0x8($25)\n\t" \ + ".set reorder" \ + :::"$25" \ + ) + +#define enable_trace_cmp_s .set noreorder; \ + lui k1,0xbfb0; \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + sw k1,-8(k1); \ + sw $0,-0x7004(k1); \ + sw $0,-0x7004(k1); \ + lw $0,-0x7004(k1); \ + lw k1,-0x8(k1); \ + .set reorder; \ + +#define write_confreg_cr(num,data) *((volatile int *)(CONFREG_CR0+4*num)) = data +#define read_confreg_cr(num,data) data=*((volatile int *)(CONFREG_CR0+4*num)) +#define NOP addu zero, zero, zero +#define LI(reg, imm) \ + li reg, imm diff --git a/resources/project/include/errno.h b/resources/project/include/errno.h new file mode 100644 index 0000000..6511597 --- /dev/null +++ b/resources/project/include/errno.h @@ -0,0 +1,39 @@ +#ifndef _ASM_GENERIC_ERRNO_BASE_H +#define _ASM_GENERIC_ERRNO_BASE_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +#endif diff --git a/resources/project/include/irq.h b/resources/project/include/irq.h new file mode 100644 index 0000000..7c40fee --- /dev/null +++ b/resources/project/include/irq.h @@ -0,0 +1,73 @@ +#ifndef MYREGS_H +#define MYREGS_H +#define IRQF_SHARED 0x00000080 +#define SA_SHIRQ IRQF_SHARED +#define IRQF_TRIGGER_NONE 0x00000000 +#define IRQF_TRIGGER_RISING 0x00000001 +#define IRQF_TRIGGER_FALLING 0x00000002 +#define IRQF_TRIGGER_HIGH 0x00000004 +#define IRQF_TRIGGER_LOW 0x00000008 +#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW) +#define IRQF_TRIGGER_PROBE 0x00000010 +struct sb2f_board_intc_regs +{ + volatile unsigned int int_isr; + volatile unsigned int int_en; + volatile unsigned int int_set; + volatile unsigned int int_clr; + volatile unsigned int int_pol; + volatile unsigned int int_edge; +}; +static struct sb2f_board_intc_regs volatile *sb2f_board_hw0_icregs = (struct sb2f_board_intc_regs volatile*)0xbfd01040; +struct irq_desc; +typedef void (*irq_flow_handler_t)(unsigned int irq,struct irq_desc *desc); +typedef int (*irq_handler_t)(void *); +struct irq_chip{ + char *name; + unsigned int (*startup)(unsigned int irq); + unsigned int (*shutdown)(unsigned int irq); + unsigned int (*enable)(unsigned int irq); + unsigned int (*disable)(unsigned int irq); + + + unsigned int (*ack)(unsigned int irq); + unsigned int (*mask)(unsigned int irq); + unsigned int (*mask_ack)(unsigned int irq); + unsigned int (*unmask)(unsigned int irq); + unsigned int (*eoi)(unsigned int irq); + + void (*end)(unsigned int irq); + int (*set_type)(unsigned int irq,unsigned int flow_type); + }; +struct irqaction{ + irq_handler_t handler; + unsigned long flags; + const char* name; + struct irqaction *next; + int irq; + void *dev_id; + }; + +struct irq_desc{ + irq_flow_handler_t handle_irq; + struct irq_chip *chip; + struct irqaction *action; + }; + +static inline int fls(int word) +{ + + __asm__(".set mips32"); + __asm__("clz %0, %1" : "=r" (word) : "r" (word)); + __asm__(".set mips0"); + return 32-word; +} +static int inline ffs(int word) +{ + if(!word) + return 0; + return fls(word & -word); +} +int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags,const char *devname, void *dev_id); +#define IRQ_RETVAL(x) ((x) != 0) +#endif diff --git a/resources/project/include/machine.h b/resources/project/include/machine.h new file mode 100644 index 0000000..d71c9b1 --- /dev/null +++ b/resources/project/include/machine.h @@ -0,0 +1,4 @@ +#ifndef __MACHINE_H_ +#define __MACHINE_H_ + +#endif diff --git a/resources/project/include/math.h b/resources/project/include/math.h new file mode 100644 index 0000000..49ce7b2 --- /dev/null +++ b/resources/project/include/math.h @@ -0,0 +1,93 @@ +/* $Id: math.h,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ +#ifndef _MATH_ +#define _MATH_ + +#ifdef FLOAT +float sin(float x); +float cos(float x); +float tan(float x); +float atan(float x); +float exp(float x); +float log(float x); +float pow(float x); +float sqrt(float x); +#else + + +double acos(double x); +double acosh(double x); +double asin(double x); +double atan(double x); +double atan2(double y, double x); +double atanh(double x); +double ceil(double x); +double cos(double x); +double cosh(double x); +double exp(double x); +double fabs(double x); +double floor(double x); +double fmod(double x, double y); +double frexp(double x, int *i); +double ldexp(double x, int i); +double log(double x); +double log10(double x); +double modf(double x, double *i); +double pow(double x,double y); +double sin(double x); +double sinh(double x); +double sqrt(double x); +double tan(double x); +double tanh(double x); + +#endif + + +float acosf(float x); +float asinf(float x); +float atan2f(float y, float x); +float atanf(float x); +float ceilf(float x); +float cosf(float x); +float coshf(float x); +float expf(float x); +float fabsf(float x); +float floorf(float x); +float fmodf(float x, float y); +float frexpf(float x, int *i); +float ldexpf(float x, int i); +float log10f(float x); +float logf(float x); +float modff(float x, float *i); +float powf(float x); +float sinf(float x); +float sinhf(float x); +float sqrtf(float x); +float tanf(float x); +float tanhf(float x); + +static inline void tgt_fpuenable() +{ +#if __mips < 3 || __mips == 32 +asm(\ +"mfc0 $2,$12;\n" \ +"li $3,0x30000000 #ST0_CU1;\n" \ +"or $2,$3;\n" \ +"mtc0 $2,$12;\n" \ +"li $2,0x00000000 #FPU_DEFAULT;\n" \ +"ctc1 $2,$31;\n" \ +:::"$2","$3" + ); +#else +asm(\ +"mfc0 $2,$12;\n" \ +"li $3,0x34000000 #ST0_CU1;\n" \ +"or $2,$3;\n" \ +"mtc0 $2,$12;\n" \ +"li $2,0x00000000 #FPU_DEFAULT;\n" \ +"ctc1 $2,$31;\n" \ +:::"$2","$3" + ); +#endif +} +#endif /* _MATH_ */ + diff --git a/resources/project/include/ns16550.h b/resources/project/include/ns16550.h new file mode 100644 index 0000000..858744f --- /dev/null +++ b/resources/project/include/ns16550.h @@ -0,0 +1,181 @@ +/* $Id: ns16550.h,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * NS16550 UART registers + */ +#ifndef __NS16550_H_ +#define __NS16550_H_ + +#define NS16550_CHANA PHYS_TO_K1(UART0_BASE) +#define NS16550_CHANB PHYS_TO_K1(UART1_BASE) + +#if (!defined(__LANGUAGE_ASSEMBLY) && !defined(_LOCORE)) + +#ifndef nsreg +#ifndef USE_SM502_UART0 +#define nsreg(x) unsigned char x +#else +#define nsreg(x) unsigned int x +#endif +#endif + +typedef struct { + nsreg(data); /* data register (R/W) */ + nsreg(ier); /* interrupt enable (W) */ + nsreg(iir); /* interrupt identification (R) */ +#define fifo iir /* 16550 fifo control (W) */ + nsreg(cfcr); /* line control register (R/W) */ + nsreg(mcr); /* modem control register (R/W) */ + nsreg(lsr); /* line status register (R/W) */ + nsreg(msr); /* modem status register (R/W) */ + nsreg(scr); /* scratch register (R/W) */ +} ns16550dev; + +extern int ns16550 __P((int, struct DevEntry *, unsigned long, int)); + +#else + +/* + * Standard speeds, make these available for start.S et al. + */ +#define B0 0 +#define B50 50 +#define B75 75 +#define B110 110 +#define B134 134 +#define B150 150 +#define B200 200 +#define B300 300 +#define B600 600 +#define B1200 1200 +#define B1800 1800 +#define B2400 2400 +#define B4800 4800 +#define B9600 9600 +#define B19200 19200 +#define B38400 38400 +#define B7200 7200 +#define B14400 14400 +#define B28800 28800 +#define B57600 57600 +#define B76800 76800 +#define B115200 115200 +#define B230400 230400 + +#endif /* __LANGUAGE_ASSEMBLY */ + +#ifndef NSREG +#define NSREG(x) x +#endif + +#define NS16550_DATA 0 +#define NS16550_IER 1 +#define NS16550_IIR 2 +#define NS16550_FIFO 2 +#define NS16550_CFCR 3 +#define NS16550_MCR 4 +#define NS16550_LSR 5 +#define NS16550_MSR 6 +#define NS16550_SCR 7 + + +/* interrupt enable register */ +#define IER_ERXRDY 0x1 /* int on rx ready */ +#define IER_ETXRDY 0x2 /* int on tx ready */ +#define IER_ERLS 0x4 /* int on line status change */ +#define IER_EMSC 0x8 /* int on modem status change */ + +/* interrupt identification register */ +#define IIR_IMASK 0xf /* mask */ +#define IIR_RXTOUT 0xc /* receive timeout */ +#define IIR_RLS 0x6 /* receive line status */ +#define IIR_RXRDY 0x4 /* receive ready */ +#define IIR_TXRDY 0x2 /* transmit ready */ +#define IIR_NOPEND 0x1 /* nothing */ +#define IIR_MLSC 0x0 /* modem status */ +#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ + +/* fifo control register */ +#define FIFO_ENABLE 0x01 /* enable fifo */ +#define FIFO_RCV_RST 0x02 /* reset receive fifo */ +#define FIFO_XMT_RST 0x04 /* reset transmit fifo */ +#define FIFO_DMA_MODE 0x08 /* enable dma mode */ +#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */ +#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */ +#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */ +#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */ + +/* character format control register */ +#define CFCR_DLAB 0x80 /* divisor latch */ +#define CFCR_SBREAK 0x40 /* send break */ +#define CFCR_PZERO 0x30 /* zero parity */ +#define CFCR_PONE 0x20 /* one parity */ +#define CFCR_PEVEN 0x10 /* even parity */ +#define CFCR_PODD 0x00 /* odd parity */ +#define CFCR_PENAB 0x08 /* parity enable */ +#define CFCR_STOPB 0x04 /* 2 stop bits */ +#define CFCR_8BITS 0x03 /* 8 data bits */ +#define CFCR_7BITS 0x02 /* 7 data bits */ +#define CFCR_6BITS 0x01 /* 6 data bits */ +#define CFCR_5BITS 0x00 /* 5 data bits */ + +/* modem control register */ +#define MCR_LOOPBACK 0x10 /* loopback */ +#define MCR_IENABLE 0x08 /* output 2 = int enable */ +#define MCR_DRS 0x04 /* output 1 = xxx */ +#define MCR_RTS 0x02 /* enable RTS */ +#define MCR_DTR 0x01 /* enable DTR */ + +/* line status register */ +#define LSR_RCV_FIFO 0x80 /* error in receive fifo */ +#define LSR_TSRE 0x40 /* transmitter empty */ +#define LSR_TXRDY 0x20 /* transmitter ready */ +#define LSR_BI 0x10 /* break detected */ +#define LSR_FE 0x08 /* framing error */ +#define LSR_PE 0x04 /* parity error */ +#define LSR_OE 0x02 /* overrun error */ +#define LSR_RXRDY 0x01 /* receiver ready */ +#define LSR_RCV_MASK 0x1f + +/* modem status register */ +#define MSR_DCD 0x80 /* DCD active */ +#define MSR_RI 0x40 /* RI active */ +#define MSR_DSR 0x20 /* DSR active */ +#define MSR_CTS 0x10 /* CTS active */ +#define MSR_DDCD 0x08 /* DCD changed */ +#define MSR_TERI 0x04 /* RI changed */ +#define MSR_DDSR 0x02 /* DSR changed */ +#define MSR_DCTS 0x01 /* CTS changed */ +#endif + diff --git a/resources/project/include/stdio.h b/resources/project/include/stdio.h new file mode 100644 index 0000000..7c16963 --- /dev/null +++ b/resources/project/include/stdio.h @@ -0,0 +1,24 @@ +#ifndef STDIO_H +#define STDIO_H + +#include + +int printf (char *fmt, ...); +int sprintf (char *buf, const char *fmt, ...); + +struct FILE{ + char* str; + size_t pos; +}; + +typedef struct FILE FILE; +#define EOF 0xFFFFFFFF + +FILE* fopen(char* str); +size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream); +void fclose(FILE* stream); +char *fgets(char *s, int size, FILE *stream); +int sscanf(const char *str, const char *fmt, ...); +int getc(FILE* stream); + +#endif diff --git a/resources/project/include/stdlib.h b/resources/project/include/stdlib.h new file mode 100644 index 0000000..845a113 --- /dev/null +++ b/resources/project/include/stdlib.h @@ -0,0 +1 @@ +#define NULL ((void *)0) diff --git a/resources/project/include/string.h b/resources/project/include/string.h new file mode 100644 index 0000000..b1a9a0e --- /dev/null +++ b/resources/project/include/string.h @@ -0,0 +1,25 @@ +#ifndef STRING_H +#define STRING_H + +size_t strlen(const char *s); +size_t strnlen(const char *s, size_t len); + +char *strcpy(char *dst, const char *src); +char *strncpy(char *dst, const char *src, size_t len); + +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, size_t n); + +char *strchr(const char *s, char c); +char *strfind(const char *s, char c); +//long strtol(const char *s, char **endptr, int base); + +void *memset(void *s, char c, size_t n); +void *memmove(void *dst, const void *src, size_t n); +void *memcpy(void *dst, const void *src, size_t n); +int memcmp(const void *v1, const void *v2, size_t n); + +void bzero(void *s, size_t n); + +#endif + diff --git a/resources/project/include/time.h b/resources/project/include/time.h new file mode 100644 index 0000000..7be1899 --- /dev/null +++ b/resources/project/include/time.h @@ -0,0 +1,46 @@ +#ifndef _TIME_H_H +#define _TIME_H_H +typedef unsigned long _clock_t; +typedef unsigned long clock_t; +#define MSEC_PER_SEC 1000L +#define USEC_PER_MSEC 1000L +#define NSEC_PER_USEC 1000L +#define NSEC_PER_MSEC 1000000L +#define USEC_PER_SEC 1000000L +#define NSEC_PER_SEC 1000000000L +#define FSEC_PER_SEC 1000000000000000LL + +struct tms{ + _clock_t tms_utime; + _clock_t tms_stime; + _clock_t tms_cutime; + _clock_t tms_cstime; +}; + +struct tm{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; +}; + +struct timespec{ + _clock_t tv_sec; + _clock_t tv_nsec; + _clock_t tv_usec; + _clock_t tv_msec; +}; + +struct timeval{ + _clock_t tv_sec; + _clock_t tv_nsec; + _clock_t tv_usec; + _clock_t tv_msec; +}; + +unsigned long get_count(); +#endif diff --git a/resources/project/lib/Makefile b/resources/project/lib/Makefile new file mode 100644 index 0000000..42b43b0 --- /dev/null +++ b/resources/project/lib/Makefile @@ -0,0 +1,21 @@ +CFLAGS := -D_KERNEL -DCONFIG_PAGE_SIZE_16KB -fno-builtin -mips1 -DCACHELOCK_MEM +CFLAGS += -DCPU_COUNT_PER_US=100 -I include -include common.h -DAPB_CLK=33333333 +CFLAGS += -DLS1FSOC -DCPU_MULT=6 -DDDR_MULT=6 -msoft-float -EL +CFLAGS += $(MEM_DEF) + +.SUFFIXES: .o64 .elf64 .bin64 + +objs= malloc.o stdio.o printf.o udelay.o now.o putchar.o puts.o printhex.o printbase.o memcmp.o strcat.o strchr.o strcmp.o strtok.o strspn.o strcspn.o getchar.o testchar.o vsprintf.o atob.o sprintf.o strtoupp.o toupper.o string.o str_fmt.o strcpy.o strichr.o strncmp.o strncpy.o newprintf.o cache.o cmdline.o irq.o guess.o strtoul.o time.o exception.o sscanf.o + +objs64=$(objs:.o=.o64) + +libtinyc.a: $(objs) + $(CROSS_COMPILE)ar -cr $@ $^ + +libtinyc64.a: $(objs64) + $(CROSS_COMPILE)ar -cr $@ $^ + +clean: + rm -f *.o *.a *.s *.o64 *.bin64 *.elf64 + +-include rules.make diff --git a/resources/project/lib/atob.c b/resources/project/lib/atob.c new file mode 100644 index 0000000..b6ea2ae --- /dev/null +++ b/resources/project/lib/atob.c @@ -0,0 +1,224 @@ +static char * _getbase __P((char *, int *)); +#ifdef HAVE_QUAD +static int _atob __P((unsigned long long *, char *p, int)); +#else +static int _atob __P((unsigned long *, char *, int)); +#endif + +static char * +_getbase(char *p, int *basep) +{ + if (p[0] == '0') { + switch (p[1]) { + case 'x': + *basep = 16; + break; + case 't': case 'n': + *basep = 10; + break; + case 'o': + *basep = 8; + break; + default: + *basep = 10; + return (p); + } + return (p + 2); + } + *basep = 10; + return (p); +} + + +/* + * _atob(vp,p,base) + */ +static int +#ifdef HAVE_QUAD +_atob (u_quad_t *vp, char *p, int base) +{ + u_quad_t value, v1, v2; +#else +_atob (unsigned long *vp, char *p, int base) +{ + u_long value, v1, v2; +#endif + char *q, tmp[20]; + int digit; + + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + base = 16; + p += 2; + } + + if (base == 16 && (q = strchr (p, '.')) != 0) { + if (q - p > sizeof(tmp) - 1) + return (0); + + strncpy (tmp, p, q - p); + tmp[q - p] = '\0'; + if (!_atob (&v1, tmp, 16)) + return (0); + + q++; + if (strchr (q, '.')) + return (0); + + if (!_atob (&v2, q, 16)) + return (0); + *vp = (v1 << 16) + v2; + return (1); + } + + value = *vp = 0; + for (; *p; p++) { + if (*p >= '0' && *p <= '9') + digit = *p - '0'; + else if (*p >= 'a' && *p <= 'f') + digit = *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + digit = *p - 'A' + 10; + else + return (0); + + if (digit >= base) + return (0); + value *= base; + value += digit; + } + *vp = value; + return (1); +} + +/* + * atob(vp,p,base) + * converts p to binary result in vp, rtn 1 on success + */ +int +atob(uint32_t *vp, char *p, int base) +{ +#ifdef HAVE_QUAD + u_quad_t v; +#else + u_long v; +#endif + + if (base == 0) + p = _getbase (p, &base); + if (_atob (&v, p, base)) { + *vp = v; + return (1); + } + return (0); +} + + +#ifdef HAVE_QUAD +/* + * llatob(vp,p,base) + * converts p to binary result in vp, rtn 1 on success + */ +int +llatob(u_quad_t *vp, char *p, int base) +{ + if (base == 0) + p = _getbase (p, &base); + return _atob(vp, p, base); +} +#endif + + +/* + * char *btoa(dst,value,base) + * converts value to ascii, result in dst + */ +char * +btoa(char *dst, u_int value, int base) +{ + char buf[34], digit; + int i, j, rem, neg; + + if (value == 0) { + dst[0] = '0'; + dst[1] = 0; + return (dst); + } + + neg = 0; + if (base == -10) { + base = 10; + if (value & (1L << 31)) { + value = (~value) + 1; + neg = 1; + } + } + + for (i = 0; value != 0; i++) { + rem = value % base; + value /= base; + if (rem >= 0 && rem <= 9) + digit = rem + '0'; + else if (rem >= 10 && rem <= 36) + digit = (rem - 10) + 'a'; + buf[i] = digit; + } + + buf[i] = 0; + if (neg) + strcat (buf, "-"); + + /* reverse the string */ + for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) + dst[i] = buf[j]; + dst[i] = 0; + return (dst); +} + +#ifdef HAVE_QUAD +/* + * char *btoa(dst,value,base) + * converts value to ascii, result in dst + */ +char * +llbtoa(char *dst, u_quad_t value, int base) +{ + char buf[66], digit; + int i, j, rem, neg; + + if (value == 0) { + dst[0] = '0'; + dst[1] = 0; + return (dst); + } + + neg = 0; + if (base == -10) { + base = 10; + if (value & (1LL << 63)) { + value = (~value) + 1; + neg = 1; + } + } + + for (i = 0; value != 0; i++) { + rem = value % base; + value /= base; + if (rem >= 0 && rem <= 9) + digit = rem + '0'; + else if (rem >= 10 && rem <= 36) + digit = (rem - 10) + 'a'; + buf[i] = digit; + } + + buf[i] = 0; + if (neg) + strcat (buf, "-"); + + /* reverse the string */ + for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) + dst[i] = buf[j]; + dst[i] = 0; + return (dst); +} +#endif + diff --git a/resources/project/lib/cache.c b/resources/project/lib/cache.c new file mode 100644 index 0000000..2d53d43 --- /dev/null +++ b/resources/project/lib/cache.c @@ -0,0 +1,49 @@ +#include +int dcache_size = 0x4000; +int icache_size = 0x4000; +#define cpu_dcache_line_size() 32 + +void dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ + if (size >= dcache_size) { + blast_dcache32(); + } else { + blast_dcache_range(addr, addr + size); + } +} + + +void dma_cache_inv(unsigned long addr, unsigned long size) +{ + + if (size >= dcache_size) { + blast_dcache32(); + } else { + unsigned long lsize = cpu_dcache_line_size(); + unsigned long almask = ~(lsize - 1); + + cache_op(Hit_Writeback_Inv_D, addr & almask); + cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & almask); + blast_inv_dcache_range(addr, addr + size); + } +} + + +void flush_icache_range(unsigned long start, unsigned long end) +{ + if (end - start >= dcache_size) { + blast_dcache32(); + } else { + protected_blast_dcache_range(start, end); + } + + if (end - start > icache_size) + blast_icache32(); + else + protected_blast_icache_range(start, end); +} diff --git a/resources/project/lib/cmdline.c b/resources/project/lib/cmdline.c new file mode 100644 index 0000000..7c4990b --- /dev/null +++ b/resources/project/lib/cmdline.c @@ -0,0 +1,186 @@ +/* + * cmdline.c + * Use command to do testing, use "help" to get more information. + * + * Created on: 2013-1-10 + * Author: liming + */ + +#include + + +int do_exit(); +int do_nothing(); +int do_help(int argc, void *argv[]); +int do_d4(int argc, char **argv); +int testguess(int argc, char **argv); + +const cmdline_t cmd[] = { + {"exit", do_exit, 0, "[exit]", "--logout"}, + {"help", do_help, 1, "[help ]", "--cmd list"}, + {"guess", testguess, 6,"","guess from to mask stide mode"}, + {"d4", do_d4, 2,"","d4 addr [count]"}, + {0, do_nothing, 0, "", ""} +}; //ÃüÁîÃû°´×Öĸ±íµÄ˳Ðò + + +int do_d4(int argc, char **argv) +{ + unsigned int addr; + int i, num; + if(argc < 2) + { + printf("\nusage: d4 "); + return 1; + } + addr = strtoul(argv[1],0,0); + if(argc == 2) num = 1; + else num = strtoul(argv[2],0,0); + + for(i=0; i0x1f)&&(c<0x7f)) //no ctrl_char + { + cmdbuffer[cp++] = c; + putchar(c); + } + else if((c == 0x8 || c == 0x7f) && cp) //backspace + { + cp--; + cmdbuffer[cp] = '\0'; + putchar(0x8); + putchar(0x20); //This is an interesting way. + putchar(0x8); + } + else if((c==0xa) || (c==0xd)) + { + break; + } + } + + if(cp == 0) + { + if(!argv[0]) + continue; + } + else + { + char *p0; + char c0, c; + for(i=0, argc=0, p0=cmdbuffer, c0=0; i1) from = strtoul(argv[1],0,0); + if(argc>2) to = strtoul(argv[2],0,0); + if(argc>3) mask = strtoul(argv[3],0,0); + if(argc>4) stride = strtoul(argv[4],0,0); + if(argc>5) mode = strtoul(argv[5],0,0); + + if(argc>2) + { + if(mode&1) + guess1(from, to); + if(mode&2) + guess(from, to); + } + else + { + if(mode&1) + guess1(0xffffffffbf000000, 0xffffffffc0000000); + if(mode&2) + guess(0xffffffffbf000000, 0xffffffffc0000000); + if(mode&1) + guess1(0xffffffff9f000000, 0xffffffffa0000000); + if(mode&2) + guess(0xffffffff9f000000, 0xffffffffa0000000); + } + return 0; +} + diff --git a/resources/project/lib/irq.c b/resources/project/lib/irq.c new file mode 100644 index 0000000..150baed --- /dev/null +++ b/resources/project/lib/irq.c @@ -0,0 +1,414 @@ +#include +#include +#include +#include + +static int no_action(int cpl, void *dev_id) +{ + return 0; +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", +}; + +unsigned int ack_sb2f_board_irq(unsigned int irq_nr) +{ + //printf("ack_sb2f_board_irq %d\n",irq_nr); + (sb2f_board_hw0_icregs+(irq_nr>>5))->int_clr |= (1 << (irq_nr & 0x1f)); +} + +unsigned int disable_sb2f_board_irq(unsigned int irq_nr) +{ + //printf("disable_sb2f_board_irq %d\n",irq_nr); + (sb2f_board_hw0_icregs+(irq_nr>>5))->int_en &= ~(1 << (irq_nr & 0x1f)); +} +unsigned int enable_sb2f_board_irq(unsigned int irq_nr) +{ + //printf("enable_sb2f_board_irq %d\n",irq_nr); + (sb2f_board_hw0_icregs+(irq_nr>>5))->int_en |= (1 << (irq_nr & 0x1f)); +} +int sb2f_board_irq_set_type(unsigned int irq,unsigned int flow_type) +{ + unsigned int irq_nr = irq; + int mode; + +} + +struct irq_chip sb2f_board_irq_chip = { + .name = "SB2F BOARD", + .ack = ack_sb2f_board_irq, + .mask = disable_sb2f_board_irq, + .unmask = enable_sb2f_board_irq, + .eoi = enable_sb2f_board_irq, + .set_type = sb2f_board_irq_set_type + }; +struct irq_desc irq_desc[256]; +int handle_IRQ_event(unsigned int irq,struct irqaction *action) +{ +// printf("I am in handle_IRQ_EVENT\n"); +#ifdef MYOPROFILE + local_irq_enable(); +#endif + do { + action->handler(action->dev_id); + action = action->next; + }while (action); +#ifdef MYOPROFILE + local_irq_disable(); +#endif +// printf("I am out handle_IRQ_EVENT\n"); +} +void handle_level_irq(unsigned int irq,struct irq_desc *desc) +{ +// printf("i am in handle_level_irq\n"); + struct irqaction *action; + desc->chip->mask(irq);/*å¯ä»¥æ¸…楚原因寄存器*/ + desc->chip->ack(irq);/*å¯ä»¥æ¸…除中断状æ€å¯„存器*/ + action = desc->action; + handle_IRQ_event(irq,action); + desc->chip->unmask(irq); +// printf("i am out handle_level_irq\n"); +} +void generic_handle_irq(unsigned int irq) +{ +// printf("i am in generic_handler_irq\n"); +// CP0_Cause(); + struct irq_desc *desc = irq_desc + irq; + desc->handle_irq(irq,desc); +// printf("i am out generic_handler_irq\n"); +} +#define do_IRQ(irq) do{ generic_handle_irq(irq);}while(0) + +void ls1gp_board_dma_irqdispatch(); + +void ls1b_board_hw_irqdispatch(int n) +{ + int irq; + int intstatus; + intstatus = (sb2f_board_hw0_icregs + n)->int_isr; + irq = ffs(intstatus); + if(!irq) + { + printf("Unknow interrpt intstatus %x\n",intstatus); + } + else if(n == 1 && irq == 11) + { + ls1gp_board_dma_irqdispatch(); + } + else do_IRQ(n*32+irq-1); +} + +void __set_irq_handler(unsigned int irq, irq_flow_handler_t handler, int is_chained, const char *name) +{ + struct irq_desc *desc; + desc = irq_desc + irq; + desc->handle_irq = handler; + +} +void default_enable(unsigned int irq) +{ + struct irq_desc *desc = irq_desc + irq; + desc->chip->unmask(irq); +} +void default_disable(unsigned int irq) +{ + +} +unsigned int default_startup(unsigned int irq) +{ + irq_desc[irq].chip->enable(irq); + return 0; +} +void irq_chip_set_defaults(struct irq_chip *chip) +{ + if(!chip->enable) + chip->enable = default_enable; + if(!chip->disable) + chip->disable = default_disable; + if(!chip->startup) + chip->startup = default_startup; + if(!chip->shutdown) + chip->shutdown = chip->disable; +} +int set_irq_chip(unsigned int irq,struct irq_chip *chip) +{ + struct irq_desc *desc; + desc = irq_desc + irq; + irq_chip_set_defaults(chip); + desc->chip = chip; + return 0; +} +void set_irq_chip_and_handler(unsigned int irq,struct irq_chip *chip,irq_flow_handler_t handle) +{ + set_irq_chip(irq,chip); + __set_irq_handler(irq, handle, 0, NULL); +} + + +/*setup dma irq */ + +struct ls1gp_cop_global_regs +{ + volatile unsigned int control; + volatile unsigned int rd_inten; + volatile unsigned int wr_inten; + volatile unsigned int rd_intisr; /* offset 0x10*/ + volatile unsigned int wr_intisr; + unsigned int unused[11]; +} ; + +#define LS1GP_BOARD_DMA_IRQ_BASE 168 +#define LS1GP_BOARD_DMA_IRQ_COUNT 16 + +static struct ls1gp_cop_global_regs *ls1gp_cop_global_regs = (void *)0xbc000000; +void ls1gp_board_dma_irqdispatch() +{ + int intstatus; + int irq; + intstatus = (ls1gp_cop_global_regs->wr_intisr & 0xff) << 8 | (ls1gp_cop_global_regs->rd_intisr & 0xff); + irq=ffs(intstatus); + if(!irq){ + printf("Unknow dma interrupt status %x \n" , intstatus); + return; + } + else do_IRQ(LS1GP_BOARD_DMA_IRQ_BASE + irq - 1); +} + +void disable_ls1gp_dma_irq(unsigned int irq) +{ + int irq_nr; + if(irq < LS1GP_BOARD_DMA_IRQ_BASE + 8) + { + irq_nr =irq - LS1GP_BOARD_DMA_IRQ_BASE; + ls1gp_cop_global_regs->rd_inten &= ~(1<wr_inten &= ~(1<rd_inten |= (1<wr_inten |= (1<rd_intisr = (1<wr_intisr = (1<action; + old = *p; + if(old) + { + do + { + p = &old->next; + old= *p; + }while(old); + shared = 1; + } + *p = newaction; + if(!shared) + { + irq_chip_set_defaults(desc->chip); + if(newaction->flags & IRQF_TRIGGER_MASK) + if(desc->chip && desc->chip->set_type) + desc->chip->set_type(irq,newaction->flags & IRQF_TRIGGER_MASK); + if(desc->chip->startup) + desc->chip->startup(irq); + else + desc->chip->enable(irq); + } + + return 0; + + +} + +int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags,const char *devname, void *dev_id) +{ + struct irqaction *action; + int retval; + if(!handler) + return -EINVAL; + action = malloc(sizeof(struct irqaction)); + if(!action) + return -ENOMEM; + action->handler = handler; + action->flags = irqflags; + action->next = NULL; + action->name = devname; + action->dev_id = dev_id; + action->irq = irq; + setup_irq(irq,action); +} + +///////interrupt +#define INT_PCI_INTA (1<<6) +#define INT_PCI_INTB (1<<7) +#define INT_PCI_INTC (1<<8) +#define INT_PCI_INTD (1<<9) +#define ST0_IM 0x0000ff00 +#define CAUSEF_IP7 ( 1 << 15) +#define CAUSEF_IP6 ( 1 << 14) +#define CAUSEF_IP5 ( 1 << 13) +#define CAUSEF_IP4 ( 1 << 12) +#define CAUSEF_IP3 ( 1 << 11) +#define CAUSEF_IP2 ( 1 << 10) +extern struct sb2f_board_intc_regs volatile *sb2f_board_hw0_icregs; +void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int cause = read_c0_cause() & ST0_IM; + unsigned int status = read_c0_status() & ST0_IM; + unsigned int pending = cause & status; + if(pending & CAUSEF_IP7) + { +#ifdef MYOPROFILE + unsigned long epc; + extern char _ftext[]; + extern int irqdepth; + /*only sample in irq*/ +#if 1 + if(irqdepth>1) +#endif + { + epc = read_c0_epc(); + if(epc>=0x80000000) (*(unsigned int *)(epc-(unsigned long)_ftext+0x84000000))++; + } + write_c0_compare(read_c0_count()+MYOPROFILE_TICK); +#else + static int cnt=0; + printf("cnt %d\n",cnt++); + write_c0_compare(read_c0_count()+100000000/100); +#endif + } + else if(pending & CAUSEF_IP2) + { + ls1b_board_hw_irqdispatch(0); + } + else if(pending & CAUSEF_IP3) + { + ls1b_board_hw_irqdispatch(1); + } + else if(pending & CAUSEF_IP4) + { + ls1b_board_hw_irqdispatch(2); + } + else if(pending & CAUSEF_IP5) + { + ls1b_board_hw_irqdispatch(3); + } + else if(pending & CAUSEF_IP6) + { + ls1b_board_hw_irqdispatch(4); + } + else + { + printf("spurious interrupt\n"); + } + +} + +void init_IRQ() +{ + int i; +#ifdef MYOPROFILE + memset((void *)0x84000000, 0, 0x200000); +#endif + + for(i = 0;i < 5;i++) + { + /* active level setting */ + /* uart, keyboard, and mouse are active high */ + (sb2f_board_hw0_icregs+i)->int_pol = -1; /*active high*/ + + /* make all interrupts level triggered */ + (sb2f_board_hw0_icregs+i)->int_edge = 0x00000000; + + /* mask all interrupts */ + (sb2f_board_hw0_icregs+i)->int_clr = 0xffffffff; + + } + + sb2f_board_irq_init(); + ls1gp_dma_irq_init(); + + setup_irq(32+10, &cascade_irqaction); + + clear_c0_status(ST0_IM); +#ifdef MYOPROFILE + write_c0_compare(MYOPROFILE_TICK); + write_c0_count(0); + set_c0_status(0xff01); +#else + set_c0_status(0x7f01); +#endif +} diff --git a/resources/project/lib/malloc.c b/resources/project/lib/malloc.c new file mode 100644 index 0000000..4736d2e --- /dev/null +++ b/resources/project/lib/malloc.c @@ -0,0 +1,135 @@ +/* $Id: malloc.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +typedef long long ALIGN; + +//static void free(void *ap); + +union header { + struct { + union header *ptr; + unsigned size; + } s; + ALIGN x; +}; + +typedef union header HEADER; + +static HEADER base; +static HEADER *allocp; /* K&R called allocp, freep */ + +#ifndef NULL +#define NULL 0 +#endif +#define NALLOC 128 + +/* The rest of this file is from pages 185-189 of K & R Edition 2 */ + +static HEADER *morecore (unsigned nbyte); + +char *membase=0x80010000; +char *sbrk(int size) +{ +char *p=membase; +membase +=size; +return p; +} + +void * +malloc(size_t nbytes) +{ + HEADER *p, *q; /* K&R called q, prevp */ + unsigned nunits; + + nunits = (nbytes + sizeof (HEADER) - 1) / sizeof (HEADER) + 1; + if ((q = allocp) == NULL) { /* no free list yet */ + base.s.ptr = allocp = q = &base; + base.s.size = 0; + } + for (p = q->s.ptr;; q = p, p = p->s.ptr) { + if (p->s.size >= nunits) { /* big enough */ + if (p->s.size == nunits) /* exactly */ + q->s.ptr = p->s.ptr; + else { /* allocate tail end */ + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + allocp = q; + return ((char *)(p + 1)); + } + if (p == allocp) + if ((p = morecore (nunits)) == NULL) + return (NULL); + } +} + + +static HEADER * +morecore(unsigned nu) +{ + char *cp; + HEADER *up; + int rnu; + + rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC); + cp = sbrk(rnu * sizeof (HEADER)); + if ((int)cp == NULL) + return (NULL); + up = (HEADER *) cp; + up->s.size = rnu; + free ((char *)(up + 1)); + return (allocp); +} + + +void +free(void *ap) +{ + HEADER *p, *q; + + p = (HEADER *) ap - 1; + for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr) + if (q >= q->s.ptr && (p > q || p < q->s.ptr)) + break; + if (p + p->s.size == q->s.ptr) { + p->s.size += q->s.ptr->s.size; + p->s.ptr = q->s.ptr->s.ptr; + } else + p->s.ptr = q->s.ptr; + if (q + q->s.size == p) { + q->s.size += p->s.size; + q->s.ptr = p->s.ptr; + } else + q->s.ptr = p; + allocp = q; +} diff --git a/resources/project/lib/memcmp.c b/resources/project/lib/memcmp.c new file mode 100644 index 0000000..5f3cbdd --- /dev/null +++ b/resources/project/lib/memcmp.c @@ -0,0 +1,16 @@ +/** + * memcmp - Compare two areas of memory + * @cs: One area of memory + * @ct: Another area of memory + * @count: The size of the area. + */ +int memcmp(const void * cs,const void * ct,int count) +{ + const unsigned char *su1, *su2; + signed char res = 0; + + for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if ((res = *su1 - *su2) != 0) + break; + return res; +} diff --git a/resources/project/lib/memcpy.c b/resources/project/lib/memcpy.c new file mode 100644 index 0000000..1dbafb6 --- /dev/null +++ b/resources/project/lib/memcpy.c @@ -0,0 +1,15 @@ +void *memcpy(void *s1, const void *s2, size_t n) +{ + const char *f = s2; + char *t = s1; + + if (f < t) { + f += n; + t += n; + while (n-- > 0) + *--t = *--f; + } else + while (n-- > 0) + *t++ = *f++; + return s1; +} diff --git a/resources/project/lib/memset.c b/resources/project/lib/memset.c new file mode 100644 index 0000000..7216b65 --- /dev/null +++ b/resources/project/lib/memset.c @@ -0,0 +1,9 @@ +void * memset(void * s,int c, size_t count) +{ + char *xs = (char *) s; + + while (count--) + *xs++ = c; + + return s; +} diff --git a/resources/project/lib/newprintf.c b/resources/project/lib/newprintf.c new file mode 100644 index 0000000..5afa8e8 --- /dev/null +++ b/resources/project/lib/newprintf.c @@ -0,0 +1,13 @@ +int +newprintf (const char *fmt, ...) +{ + int len; + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + len = vsprintf (buf, fmt, ap); + va_end(ap); + putstring(buf); + return (len); +} diff --git a/resources/project/lib/now.c b/resources/project/lib/now.c new file mode 100644 index 0000000..14fdf3c --- /dev/null +++ b/resources/project/lib/now.c @@ -0,0 +1,6 @@ +int now() +{ +int count; +asm volatile("mfc0 %0,$9":"=r"(count)); +return count; +} diff --git a/resources/project/lib/printbase.c b/resources/project/lib/printbase.c new file mode 100644 index 0000000..2d39a72 --- /dev/null +++ b/resources/project/lib/printbase.c @@ -0,0 +1,28 @@ +int printbase(long v,int w,int base,int sign) +{ + int i,j; + int c; + char buf[64]; + unsigned long value; + if(sign && v<0) + { + value = -v; + putchar('-'); + } + else value=v; + + for(i=0;value;i++) + { + buf[i]=value%base; + value=value/base; + } + +#define max(a,b) (((a)>(b))?(a):(b)) + + for(j=max(w,i);j>0;j--) + { + c=j>i?0:buf[j-1]; + putchar((c<=9)?c+'0':c-0xa+'a'); + } + return 0; +} diff --git a/resources/project/lib/printf.c b/resources/project/lib/printf.c new file mode 100644 index 0000000..e9dbfaf --- /dev/null +++ b/resources/project/lib/printf.c @@ -0,0 +1,84 @@ +int printf(const char *fmt,...) +{ +int i; +char c; +void **arg; +void *ap; +int w; +__builtin_va_start(ap,fmt); +arg=ap; +for(i=0;fmt[i];i++) +{ + c=fmt[i]; + if(c=='%') + { + w=1; +again: + switch(fmt[i+1]) + { + case 's': + putstring(*arg); + arg++; + i++; + break; + case 'c': + putchar((long)*arg); + arg++; + i++; + break; + case 'u': + printbase((long)*arg,w,10,0); + arg++; + i++; + break; + case 'd': + printbase((long)*arg,w,10,1); + arg++; + i++; + break; + case 'l': + printbase((long)*arg,w,10,0); + arg++; + i=i+2; + break; + case 'o': + printbase((long)*arg,w,8,0); + arg++; + i++; + break; + case 'b': + printbase((long)*arg,w,2,0); + arg++; + i++; + break; + case 'p': + case 'x': + printbase((long)*arg,w,16,0); + arg++; + i++; + break; + case '%': + putchar('%'); + i++; + break; + case '0': + i++; + case '1' ... '9': + for(w=0;fmt[i+1]>'0' && fmt[i+1]<='9';i++) + w=w*10+(fmt[i+1]-'0'); + goto again; + break; + + default: + putchar('%'); + break; + } + + } + else{ + if(c=='\n') putchar('\r'); + putchar(c); + } +} + return 0; +} diff --git a/resources/project/lib/printhex.c b/resources/project/lib/printhex.c new file mode 100644 index 0000000..1cb12bb --- /dev/null +++ b/resources/project/lib/printhex.c @@ -0,0 +1,11 @@ +int printhex(long v,int w) +{ + int i; + int c; + for(i=4*(w-1);i>=0;i-=4) + { + c=(v>>i)&0xf; + putchar((c<=9)?c+'0':c-0xa+'a'); + } + return 0; +} diff --git a/resources/project/lib/putchar.c b/resources/project/lib/putchar.c new file mode 100644 index 0000000..ed8dd11 --- /dev/null +++ b/resources/project/lib/putchar.c @@ -0,0 +1,18 @@ +int putchar(int c) +{ +tgt_putchar(c); +return 0; +} + +void tgt_putchar(c) +{ + asm( + ".set noreorder\n\t" + "lui $25, 0xbfb0\n\t" + "jr $31\n\t" + "sb %0,-0x10($25)\n\t" + ".set reorder\n\t" + : + :"r"(c) + :"$25"); +} diff --git a/resources/project/lib/puts.c b/resources/project/lib/puts.c new file mode 100644 index 0000000..8a5dcc8 --- /dev/null +++ b/resources/project/lib/puts.c @@ -0,0 +1,20 @@ +int putstring(char *s) +{ +char c; +while((c=*s)) +{ + if(c == '\n') putchar('\r'); + putchar(c); + s++; +} +return 0; +} + + +int puts(char *s) +{ +putstring(s); +putchar('\r'); +putchar('\n'); +return 0; +} diff --git a/resources/project/lib/rules.make b/resources/project/lib/rules.make new file mode 100644 index 0000000..ab4781b --- /dev/null +++ b/resources/project/lib/rules.make @@ -0,0 +1,16 @@ +.S.o: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -c $< -nostdinc -nostdlib +.c.o: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -c $< -nostdinc -nostdlib +.S.o64: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -o $@ -c $< -nostdinc -nostdlib -mabi=64 +.c.o64: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -o $@ -c $< -nostdinc -nostdlib -mabi=64 +.S.s: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -S -fverbose-asm -o $@ $< -nostdinc -nostdlib +.c.s: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -S -fverbose-asm -o $@ $< -nostdinc -nostdlib +.S.s64: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -S -fverbose-asm -o $@ -c $< -nostdinc -nostdlib -mabi=64 +.c.s64: + ${CROSS_COMPILE}gcc -O2 $(CFLAGS) -fno-pic -mno-abicalls -g -DGUEST -I ../include -I . -S -fverbose-asm -o $@ -c $< -nostdinc -nostdlib -mabi=64 diff --git a/resources/project/lib/sprintf.c b/resources/project/lib/sprintf.c new file mode 100644 index 0000000..3fc0a98 --- /dev/null +++ b/resources/project/lib/sprintf.c @@ -0,0 +1,25 @@ +/* + * sprintf(buf,fmt,va_alist) send formatted string to buf + */ +int +sprintf (char *buf, const char *fmt, ...) +{ + int n; + va_list ap; + + va_start(ap, fmt); + n = vsprintf (buf, fmt, ap); + va_end(ap); + return (n); +} +int +snprintf (char *buf, size_t maxlen, const char *fmt, ...) +{ + int n; + va_list ap; + + va_start(ap, fmt); + n = vsprintf (buf, fmt, ap); + va_end(ap); + return (n); +} diff --git a/resources/project/lib/sscanf.c b/resources/project/lib/sscanf.c new file mode 100644 index 0000000..5928266 --- /dev/null +++ b/resources/project/lib/sscanf.c @@ -0,0 +1,512 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 G. Elian Gidoni + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +/* + * Private functions. + */ + +static int +is_space(char c) +{ + return (c == ' ' || c == '\t' || c == '\v' || + c == '\f' || c == '\r' || c == '\n'); +} + +static char* +skip_spaces(const char *str) +{ + while (is_space(*str)){ + ++str; + } + return (char*)str; +} + +/* Returns a pointer after the last read char, or 'str' on error. */ +static char* +dec_to_signed(const char *str, long *out) +{ + const char * cur = skip_spaces(str); + long value = 0; + int isneg = 0, isempty = 1; + if (cur[0] == '+'){ + cur += 1; + }else if(cur[0] == '-'){ + cur += 1; + isneg = 1; + } + while (*cur != '\0' && *cur >= '0' && *cur <= '9'){ + value = (value * 10) + (*cur - '0'); + isempty = 0; + ++cur; + } + if (isempty){ + return (char*)str; + } + if (isneg){ + *out = -value; + }else{ + *out = value; + } + return (char*)cur; +} + +/* Returns a pointer after the last read char, or 'str' on error. */ +static char* +dec_to_unsigned(const char *str, unsigned long *out) +{ + const char * cur = skip_spaces(str); + unsigned long value = 0; + int isempty = 1; + while (*cur != '\0' && *cur >= '0' && *cur <= '9'){ + value = (value * 10) + (*cur - '0'); + isempty = 0; + ++cur; + } + if (isempty){ + return (char*)str; + } + *out = value; + return (char*)cur; +} + +/* Returns a pointer after the last read char, or 'str' on error. */ +static char* +hex_to_signed(const char *str, long *out) +{ + const char * cur = skip_spaces(str); + long value = 0; + int isneg = 0, isempty = 1; + if (cur[0] == '+'){ + cur += 1; + }else if(cur[0] == '-'){ + cur += 1; + isneg = 1; + } + if (cur[0] == '0' && cur[1] == 'x'){ + cur += 2; + } + while (*cur != '\0'){ + if(*cur >= '0' && *cur <= '9'){ + value = (value * 16) + (*cur - '0'); + }else if (*cur >= 'a' && *cur <= 'f'){ + value = (value * 16) + 10 + (*cur - 'a'); + }else if (*cur >= 'A' && *cur <= 'F'){ + value = (value * 16) + 10 + (*cur - 'A'); + }else{ + break; + } + isempty = 0; + ++cur; + } + if (isempty){ + return (char*)str; + } + if (isneg){ + *out = -value; + }else{ + *out = value; + } + return (char*)cur; +} + +/* Returns a pointer after the last read char, or 'str' on error. */ +static char* +hex_to_unsigned(const char *str, unsigned long *out) +{ + const char * cur = skip_spaces(str); + unsigned long value = 0; + int isempty = 1; + if (cur[0] == '0' && cur[1] == 'x'){ + cur += 2; + } + while (*cur != '\0'){ + if(*cur >= '0' && *cur <= '9'){ + value = (value * 16) + (*cur - '0'); + }else if (*cur >= 'a' && *cur <= 'f'){ + value = (value * 16) + 10 + (*cur - 'a'); + }else if (*cur >= 'A' && *cur <= 'F'){ + value = (value * 16) + 10 + (*cur - 'A'); + }else{ + break; + } + isempty = 0; + ++cur; + } + if (isempty){ + return (char*)str; + } + *out = value; + return (char*)cur; +} + +#define MFMT_DEC_TO_SIGNED(TYPE, NAME) \ +static char* \ +dec_to_##NAME(const char *str, TYPE *out) \ +{ \ + long v; \ + char *cur = dec_to_signed(str, &v); \ + if (cur != str){ \ + *out = (TYPE)v; \ + } \ + return cur; \ +} + +#define MFMT_DEC_TO_UNSIGNED(TYPE, NAME) \ +static char* \ +dec_to_##NAME(const char *str, TYPE *out) \ +{ \ + unsigned long v; \ + char *cur = dec_to_unsigned(str, &v); \ + if (cur != str){ \ + *out = (TYPE)v; \ + } \ + return cur; \ +} + +#define MFMT_HEX_TO_SIGNED(TYPE, NAME) \ +static char* \ +hex_to_##NAME(const char *str, TYPE *out) \ +{ \ + long v; \ + char *cur = hex_to_signed(str, &v); \ + if (cur != str){ \ + *out = (TYPE)v; \ + } \ + return cur; \ +} + +#define MFMT_HEX_TO_UNSIGNED(TYPE, NAME) \ +static char* \ +hex_to_##NAME(const char *str, TYPE *out) \ +{ \ + unsigned long v; \ + char *cur = hex_to_unsigned(str, &v); \ + if (cur != str){ \ + *out = (TYPE)v; \ + } \ + return cur; \ +} + +/* Returns a pointer after the last written char, or 'str' on error. */ +#define MFMT_SIGNED_TO_HEX(TYPE, NAME) \ +static char* \ +NAME##_to_hex(TYPE val, int uppercase, char padchar, size_t padlen, \ + size_t len, char *str) \ +{ \ + char buf[24]; \ + size_t isneg = 0, cnt = 0; \ + if (uppercase){ \ + uppercase = 'A'; \ + }else{ \ + uppercase = 'a'; \ + } \ + if (val < 0){ \ + isneg = 1; \ + val = -val; \ + } \ + do{ \ + buf[cnt++] = val % 16; \ + val = val / 16; \ + }while (val != 0); \ + if (padlen > isneg + cnt){ \ + padlen -= isneg + cnt; \ + padlen = (padlen < len ? padlen : len); \ + memset(str, padchar, padlen); \ + str += padlen; \ + len -= padlen; \ + } \ + if (isneg && len > 0){ \ + str[0] = '-'; \ + str += 1; \ + len -= 1; \ + } \ + while (cnt-- > 0 && len-- > 0){ \ + if (buf[cnt] < 10){ \ + *str = buf[cnt] + '0'; \ + }else{ \ + *str = (buf[cnt] - 10) + uppercase; \ + } \ + ++str; \ + } \ + return str; \ +} + +/* Returns a pointer after the last written char, or 'str' on error. */ +#define MFMT_SIGNED_TO_DEC(TYPE, NAME) \ +static char* \ +NAME##_to_dec(TYPE val, char padchar, size_t padlen, \ + size_t len, char *str) \ +{ \ + char buf[24]; \ + size_t isneg = 0, cnt = 0; \ + if (val < 0){ \ + isneg = 1; \ + val = -val; \ + } \ + do{ \ + buf[cnt++] = val % 10; \ + val = val / 10; \ + }while (val != 0); \ + if (padlen > isneg + cnt){ \ + padlen -= isneg + cnt; \ + padlen = (padlen < len ? padlen : len); \ + memset(str, padchar, padlen); \ + str += padlen; \ + len -= padlen; \ + } \ + if (isneg && len > 0){ \ + str[0] = '-'; \ + str += 1; \ + len -= 1; \ + } \ + while (cnt-- > 0 && len-- > 0){ \ + *str = buf[cnt] + '0'; \ + ++str; \ + } \ + return str; \ +} + +/* Returns a pointer after the last written char, or 'str' on error. */ +#define MFMT_UNSIGNED_TO_HEX(TYPE, NAME) \ +static char* \ +NAME##_to_hex(TYPE val, int uppercase, char padchar, size_t padlen, \ + size_t len, char *str) \ +{ \ + char buf[24]; \ + size_t cnt = 0; \ + if (uppercase){ \ + uppercase = 'A'; \ + }else{ \ + uppercase = 'a'; \ + } \ + do{ \ + buf[cnt++] = val % 16; \ + val = val / 16; \ + }while (val != 0); \ + if (padlen > cnt){ \ + padlen -= cnt; \ + padlen = (padlen < len ? padlen : len); \ + memset(str, padchar, padlen); \ + str += padlen; \ + len -= padlen; \ + } \ + while (cnt-- > 0 && len-- > 0){ \ + if (buf[cnt] < 10){ \ + *str = buf[cnt] + '0'; \ + }else{ \ + *str = (buf[cnt] - 10) + uppercase; \ + } \ + ++str; \ + } \ + return str; \ +} + +/* Returns a pointer after the last written char, or 'str' on error. */ +#define MFMT_UNSIGNED_TO_DEC(TYPE, NAME) \ +static char* \ +NAME##_to_dec(TYPE val, char padchar, size_t padlen, \ + size_t len, char *str) \ +{ \ + char buf[24]; \ + size_t cnt = 0; \ + do{ \ + buf[cnt++] = val % 10; \ + val = val / 10; \ + }while (val != 0); \ + if (padlen > cnt){ \ + padlen -= cnt; \ + padlen = (padlen < len ? padlen : len); \ + memset(str, padchar, padlen); \ + str += padlen; \ + len -= padlen; \ + } \ + while (cnt-- > 0 && len-- > 0){ \ + *str = buf[cnt] + '0'; \ + ++str; \ + } \ + return str; \ +} + +MFMT_DEC_TO_SIGNED(int, int) +MFMT_HEX_TO_SIGNED(int, int) +MFMT_SIGNED_TO_DEC(int, int) +MFMT_SIGNED_TO_HEX(int, int) + +MFMT_DEC_TO_UNSIGNED(unsigned int, uint) +MFMT_HEX_TO_UNSIGNED(unsigned int, uint) +MFMT_UNSIGNED_TO_DEC(unsigned int, uint) +MFMT_UNSIGNED_TO_HEX(unsigned int, uint) +MFMT_UNSIGNED_TO_HEX(size_t, siz) + +static const char* +parse_arg(const char *fmt, const char *str, va_list args) +{ + int *intp, intv = 0; + unsigned int *uintp, uintv = 0, width = 0; + char *charp; + const char *cur = str; + fmt = dec_to_uint(fmt, &width); + if (*fmt == 'd'){ + cur = dec_to_int(str, &intv); + if (cur != str){ + intp = va_arg(args, int*); + *intp = intv; + } + }else if (*fmt == 'u'){ + cur = dec_to_uint(str, &uintv); + if (cur != str){ + uintp = va_arg(args, unsigned int*); + *uintp = uintv; + } + }else if (*fmt == 'x' || *fmt == 'X'){ + cur = hex_to_uint(str, &uintv); + if (cur != str){ + uintp = va_arg(args, unsigned int*); + *uintp = uintv; + } + }else if (*fmt == 'c'){ + charp = va_arg(args, char*); + if (width == 0){ + width = 1; + } + while (cur[0] != '\0' && uintv < width){ + charp[uintv] = cur[0]; + ++cur; + ++uintv; + } + }else if (*fmt == 's'){ + charp = va_arg(args, char*); + while (cur[0] != '\0' && ! is_space(cur[0]) && + (width == 0 || uintv < width)){ + charp[uintv] = cur[0]; + ++cur; + ++uintv; + } + charp[uintv] = '\0'; + }else if (*fmt == '%' && str[0] == '%'){ + ++cur; + } + return cur; +} + +static char* +print_arg(const char *fmt, char *str, size_t len, va_list args) +{ + unsigned int uintv, width = 0; + size_t charplen = 0, padlen = 0; + int intv; + char *charp, padchar = (*fmt == '0' ? '0' : ' '); + fmt = dec_to_uint(fmt, &width); + if (*fmt == 'd' || *fmt == 'i'){ + intv = va_arg(args, int); + str = int_to_dec(intv, padchar, width, len, str); + }else if (*fmt == 'u'){ + uintv = va_arg(args, unsigned int); + str = uint_to_dec(uintv, padchar, width, len, str); + }else if (*fmt == 'x' || *fmt == 'X'){ + uintv = va_arg(args, unsigned int); + str = uint_to_hex(uintv, (*fmt == 'X'), padchar, width, + len, str); + }else if (*fmt == 'p'){ + charp = (char*)va_arg(args, void*); + str = siz_to_hex((size_t)charp, 0, padchar, width, + len, str); + }else if (*fmt == 'c'){ + intv = va_arg(args, int); + if (width > 1){ + padlen = (size_t)width - 1; + padlen = (padlen < len ? padlen : len); + memset(str, ' ', padlen); + str += padlen; + len -= padlen; + } + if (len > 0){ + str[0] = (char) intv; + str += 1; + len -= 1; + } + }else if (*fmt == 's'){ + charp = va_arg(args, char*); + charplen = strlen(charp); + if (width > 0 && (size_t)width > charplen){ + padlen = (size_t)width - charplen; + padlen = (padlen < len ? padlen : len); + memset(str, ' ', padlen); + str += padlen; + len -= padlen; + } + charplen = (charplen < len ? charplen : len); + memcpy(str, charp, charplen); + str += charplen; + len -= charplen; + }else if (*fmt == '%'){ + str[0] = '%'; + ++str; + } + return str; +} + +/* + * Public functions. + */ + +int +sscanf(const char *str, const char *fmt, ...) +{ + int ret = 0; + va_list args; + va_start(args, fmt); + while (fmt[0] != '\0' && str[0] != '\0'){ + if (fmt[0] == '%'){ + const char * tmp = parse_arg(&fmt[1], str, args); + if (tmp == str){ + break; + } + if (fmt[1] != '%'){ + ++ret; + } + ++fmt; + while (fmt[0] >= '0' && fmt[0] <= '9'){ + ++fmt; + } + ++fmt; + str = tmp; + }else if (is_space(fmt[0])){ + ++fmt; + str = skip_spaces(str); + }else if (fmt[0] == str[0]){ + ++fmt; + ++str; + }else{ + break; + } + } + + va_end(args); + return ret; +} + diff --git a/resources/project/lib/stdio.c b/resources/project/lib/stdio.c new file mode 100644 index 0000000..b7da880 --- /dev/null +++ b/resources/project/lib/stdio.c @@ -0,0 +1,97 @@ +#include +#include + +#define SIZE 10 +FILE files[SIZE] = {0}; +/* + +FILE* fopen(char* str){ + FILE* file = &dummy; + while(file->next != NULL){ + file = file->next; + } + file->next = malloc(sizeof(*file)); + file->next->str = str; + file->next->pos = 0; + file->next->next = NULL; + return file->next; +} +*/ +FILE* fopen(char* str){ + int i; + for(i=0;istr; + size_t total = strlen(str); + if(stream->pos == total){ + return 0; + } + size_t c = 0; + for(c=0;cpos++]; + if(stream->pos == total){ + break; + } + } + return c; +} + +/* +void fclose(FILE* stream){ + FILE* file = &dummy; + while(file->next != stream){ + file = file->next; + } + FILE* tmp = file->next; + file->next = tmp->next; + free(tmp); +} +*/ + +void fclose(FILE* stream){ + int i; + for(i=0;istr = NULL; + stream->pos = 0; +} + +char *fgets(char *s, int size, FILE *stream){ + char* str = stream->str; + size_t total = strlen(str); + size_t c = 0; + char* r = NULL; + while(stream->pos != total){ + if(str[stream->pos] == '\n'){ + s[c++] = str[stream->pos++]; + break; + }else{ + s[c++] = str[stream->pos++]; + } + } + return r; +} + +int getc(FILE* stream){ + char* str = stream->str; + size_t total = strlen(str); + if(stream->pos == total){ + return EOF; + }else{ + return (unsigned char)str[stream->pos++]; + } + +} diff --git a/resources/project/lib/str_fmt.c b/resources/project/lib/str_fmt.c new file mode 100644 index 0000000..690c6ea --- /dev/null +++ b/resources/project/lib/str_fmt.c @@ -0,0 +1,33 @@ +/* + * Format string by inserting blanks. + */ + +void +str_fmt(char *p, int size, int fmt) +{ + int n, m, len; + + len = strlen (p); + switch (fmt) { + case FMT_RJUST: + for (n = size - len; n > 0; n--) + strichr (p, ' '); + break; + case FMT_LJUST: + for (m = size - len; m > 0; m--) + strcat (p, " "); + break; + case FMT_RJUST0: + for (n = size - len; n > 0; n--) + strichr (p, '0'); + break; + case FMT_CENTER: + m = (size - len) / 2; + n = size - (len + m); + for (; m > 0; m--) + strcat (p, " "); + for (; n > 0; n--) + strichr (p, ' '); + break; + } +} diff --git a/resources/project/lib/strcat.c b/resources/project/lib/strcat.c new file mode 100644 index 0000000..5825675 --- /dev/null +++ b/resources/project/lib/strcat.c @@ -0,0 +1,48 @@ +/* $Id: strcat.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +char * +strcat(char *dst, const char *src) +{ + char *d; + + if (!dst || !src) + return (dst); + + d = dst; + for (; *d; d++); + for (; *src; src++) + *d++ = *src; + *d = 0; + return (dst); +} diff --git a/resources/project/lib/strchr.c b/resources/project/lib/strchr.c new file mode 100644 index 0000000..30c86b8 --- /dev/null +++ b/resources/project/lib/strchr.c @@ -0,0 +1,44 @@ +/* $Id: strchr.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +char * +strchr(const char *p, int c) +{ + if (!p) + return (0); + + for (; *p; p++) + if (*p == c) + return ((char *)p); + return (0); +} diff --git a/resources/project/lib/strcmp.c b/resources/project/lib/strcmp.c new file mode 100644 index 0000000..406b0d0 --- /dev/null +++ b/resources/project/lib/strcmp.c @@ -0,0 +1,11 @@ +/* + * Compare strings. + */ +int +strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + return (*(const unsigned char *)s1 - *(const unsigned char *)--s2); +} diff --git a/resources/project/lib/strcpy.c b/resources/project/lib/strcpy.c new file mode 100644 index 0000000..baf91b2 --- /dev/null +++ b/resources/project/lib/strcpy.c @@ -0,0 +1,36 @@ +#include + +char * +strcpy (char *dstp, const char *srcp) +{ + char *dp = dstp; + + if (!dstp) + return (0); + *dp = 0; + if (!srcp) + return (dstp); + + while ((*dp++ = *srcp++) != 0); + return (dstp); +} + +size_t +strlcpy(char *d, const char *s, size_t l) +{ + size_t len = l; + + if (d == NULL || l == 0) + return 0; + *d = 0; + if (s == NULL) + return 0; + + while (--len) + if ((*d++ = *s++) == 0) + break; + if (len == 0) + *d = 0; + len = l - len; + return len; +} diff --git a/resources/project/lib/strcspn.c b/resources/project/lib/strcspn.c new file mode 100644 index 0000000..f9f8a69 --- /dev/null +++ b/resources/project/lib/strcspn.c @@ -0,0 +1,48 @@ +/* $Id: strcspn.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +int +strcspn (const char *p, const char *s) +{ + int i, j; + + for (i = 0; p[i]; i++) { + for (j = 0; s[j]; j++) { + if (s[j] == p[i]) + break; + } + if (s[j]) + break; + } + return (i); +} diff --git a/resources/project/lib/strichr.c b/resources/project/lib/strichr.c new file mode 100644 index 0000000..fc91579 --- /dev/null +++ b/resources/project/lib/strichr.c @@ -0,0 +1,16 @@ +#include + +char * +strichr(char *p, int c) +{ + char *t; + + if (p != NULL) { + for(t = p; *t; t++); + for (; t >= p; t--) { + *(t + 1) = *t; + } + *p = c; + } + return (p); +} diff --git a/resources/project/lib/string.c b/resources/project/lib/string.c new file mode 100644 index 0000000..3b8b5a6 --- /dev/null +++ b/resources/project/lib/string.c @@ -0,0 +1,346 @@ +#include +#include + +/* * + * strlen - calculate the length of the string @s, not including + * the terminating '\0' character. + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + size_t cnt = 0; + while (*s ++ != '\0') { + cnt ++; + } + return cnt; +} + +/* * + * strnlen - calculate the length of the string @s, not including + * the terminating '\0' char acter, but at most @len. + * @s: the input string + * @len: the max-length that function will scan + * + * Note that, this function looks only at the first @len characters + * at @s, and never beyond @s + @len. + * + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + size_t cnt = 0; + while (cnt < len && *s ++ != '\0') { + cnt ++; + } + return cnt; +} + +/* * + * strcpy - copies the string pointed by @src into the array pointed by @dst, + * including the terminating null character. + * @dst: pointer to the destination array where the content is to be copied + * @src: string to be copied + * + * The return value is @dst. + * + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { +#ifdef __HAVE_ARCH_MEM_OPTS + return __strcpy(dst, src); +#else + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_MEM_OPTS */ +} + +/* * + * strncpy - copies the first @len characters of @src to @dst. If the end of string @src + * if found before @len characters have been copied, @dst is padded with '\0' until a + * total of @len characters have been written to it. + * @dst: pointer to the destination array where the content is to be copied + * @src: string to be copied + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + char *p = dst; + while (len > 0) { + if ((*p = *src) != '\0') { + src ++; + } + p ++, len --; + } + return dst; +} + +/* * + * strncmp - compares up to @n characters of the string @s1 to those of the string @s2 + * @s1: string to be compared + * @s2: string to be compared + * @n: maximum number of characters to compare + * + * This function starts comparing the first character of each string. If + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + n --, s1 ++, s2 ++; + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); +} + +/* * + * strchr - locates first occurrence of character in string + * @s: the input string + * @c: character to be located + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + while (*s != '\0') { + if (*s == c) { + return (char *)s; + } + s ++; + } + return NULL; +} + +/* * + * strfind - locates first occurrence of character in string + * @s: the input string + * @c: character to be located + * + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + while (*s != '\0') { + if (*s == c) { + break; + } + s ++; + } + return (char *)s; +} + +/* * + * strtol - converts string to long integer + * @s: the input string that contains the representation of an integer number + * @endptr: reference to an object of type char *, whose value is set by the + * function to the next character in @s after the numerical value. This + * parameter can also be a null pointer, in which case it is not used. + * @base: x + * + * The function first discards as many whitespace characters as necessary until + * the first non-whitespace character is found. Then, starting from this character, + * takes as many characters as possible that are valid following a syntax that + * depends on the base parameter, and interprets them as a numerical value. Finally, + * a pointer to the first character following the integer representation in @s + * is stored in the object pointed by @endptr. + * + * If the value of base is zero, the syntax expected is similar to that of + * integer constants, which is formed by a succession of: + * - An optional plus or minus sign; + * - An optional prefix indicating octal or hexadecimal base ("0" or "0x" respectively) + * - A sequence of decimal digits (if no base prefix was specified) or either octal + * or hexadecimal digits if a specific prefix is present + * + * If the base value is between 2 and 36, the format expected for the integral number + * is a succession of the valid digits and/or letters needed to represent integers of + * the specified radix (starting from '0' and up to 'z'/'Z' for radix 36). The + * sequence may optionally be preceded by a plus or minus sign and, if base is 16, + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +#if 0 +long +strtol(const char *s, char **endptr, int base) { + int neg = 0; + long val = 0; + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + s ++; + } + + // plus/minus sign + if (*s == '+') { + s ++; + } + else if (*s == '-') { + s ++, neg = 1; + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + s += 2, base = 16; + } + else if (base == 0 && s[0] == '0') { + s ++, base = 8; + } + else if (base == 0) { + base = 10; + } + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + dig = *s - '0'; + } + else if (*s >= 'a' && *s <= 'z') { + dig = *s - 'a' + 10; + } + else if (*s >= 'A' && *s <= 'Z') { + dig = *s - 'A' + 10; + } + else { + break; + } + if (dig >= base) { + break; + } + s ++, val = (val * base) + dig; + // we don't properly detect overflow! + } + + if (endptr) { + *endptr = (char *) s; + } + return (neg ? -val : val); +} +#endif + +/* * + * memset - sets the first @n bytes of the memory area pointed by @s + * to the specified value @c. + * @s: pointer the the memory area to fill + * @c: value to set + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { +#ifdef __HAVE_ARCH_MEM_OPTS + return __memset(s, c, n); +#else + char *p = s; + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEM_OPTS */ +} + +/* * + * memcpy - copies the value of @n bytes from the location pointed by @src to + * the memory area pointed by @dst. + * @dst pointer to the destination array where the content is to be copied + * @src pointer to the source of data to by copied + * @n: number of bytes to copy + * + * The memcpy() returns @dst. + * + * Note that, the function does not check any terminating null character in @src, + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { +#ifdef __HAVE_ARCH_MEM_OPTS + return __memcpy(dst, src, n); +#else + const char *s = src; + char *d = dst; + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEM_OPTS */ +} + +/* * + * memmove - copies the values of @n bytes from the location pointed by @src to + * the memory area pointed by @dst. @src and @dst are allowed to overlap. + * @dst pointer to the destination array where the content is to be copied + * @src pointer to the source of data to by copied + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { +#ifdef __HAVE_ARCH_MEM_OPTS + return __memmove(dst, src, n); +#else + const char *s = src; + char *d = dst; + if (s < d && s + n > d) { + s += n, d += n; + while (n -- > 0) { + *-- d = *-- s; + } + } else { + while (n -- > 0) { + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEM_OPTS */ +} + +/* * + * memcmp - compares two blocks of memory + * @v1: pointer to block of memory + * @v2: pointer to block of memory + * @n: number of bytes to compare + * + * The memcmp() functions returns an integral value indicating the + * relationship between the content of the memory blocks: + * - A zero value indicates that the contents of both memory blocks are equal; + * - A value greater than zero indicates that the first byte that does not + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + const char *s1 = (const char *)v1; + const char *s2 = (const char *)v2; + while (n -- > 0) { + if (*s1 != *s2) { + return (int)((unsigned char)*s1 - (unsigned char)*s2); + } + s1 ++, s2 ++; + } + return 0; +} + +void bzero(void *s, size_t n){ + memset(s, 0, n); +} + diff --git a/resources/project/lib/strncmp.c b/resources/project/lib/strncmp.c new file mode 100644 index 0000000..a8b4fec --- /dev/null +++ b/resources/project/lib/strncmp.c @@ -0,0 +1,17 @@ +int +strncmp(const char *s1, const char *s2, size_t n) +{ + if (!s1 || !s2) + return (0); + + while (n && (*s1 == *s2)) { + if (*s1 == 0) + return (0); + s1++; + s2++; + n--; + } + if (n) + return (*s1 - *s2); + return (0); +} diff --git a/resources/project/lib/strncpy.c b/resources/project/lib/strncpy.c new file mode 100644 index 0000000..9dc658e --- /dev/null +++ b/resources/project/lib/strncpy.c @@ -0,0 +1,14 @@ +char * +strncpy(char *dst, const char *src, size_t n) +{ + char *d; + + if (!dst || !src) + return (dst); + d = dst; + for (; *src && n; d++, src++, n--) + *d = *src; + while (n--) + *d++ = '\0'; + return (dst); +} diff --git a/resources/project/lib/strspn.c b/resources/project/lib/strspn.c new file mode 100644 index 0000000..240b1ed --- /dev/null +++ b/resources/project/lib/strspn.c @@ -0,0 +1,51 @@ +/* $Id: strspn.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* return length of initial segment of p that consists entirely of + * characters from s */ + +int +strspn(const char *p, const char *s) +{ + int i, j; + + for (i = 0; p[i]; i++) { + for (j = 0; s[j]; j++) { + if (s[j] == p[i]) + break; + } + if (!s[j]) + break; + } + return (i); +} diff --git a/resources/project/lib/strtok.c b/resources/project/lib/strtok.c new file mode 100644 index 0000000..a8ca3b5 --- /dev/null +++ b/resources/project/lib/strtok.c @@ -0,0 +1,51 @@ +/* $Id: strtok.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +char * +strtok(char *p, const char *tok) +{ +static char *t; /* XXX */ + char *r; + int n; + + if (p) + t = p; + + r = t + strspn (t, tok); + if (!(n = strcspn (r, tok))) + return (0); + t = r + n; + if (*t) + *t++ = 0; + return (r); +} diff --git a/resources/project/lib/strtoul.c b/resources/project/lib/strtoul.c new file mode 100644 index 0000000..2c7a12c --- /dev/null +++ b/resources/project/lib/strtoul.c @@ -0,0 +1,81 @@ +#include + +#define ULONG_MAX 4294967295UL +#define LONG_MAX 2147483647L +#define LONG_MIN (-LONG_MAX-1) +#define isspace(c) (c==0x20) +#define isdigit(c) (((c) >= '0') && ((c) <= '9')) +#define isalpha(c) ( (((c) >= 'A') && ((c) <= 'Z')) || \ + (((c) >= 'a') && ((c) <= 'z')) ) +#define isupper(c) (c>='A' && c<='Z') + +unsigned long +strtoul(const char *nptr,char **endptr,int base) +{ + int c; + unsigned long result = 0L; + unsigned long limit; + int negative = 0; + int overflow = 0; + int digit; + + while ((c = *nptr) && isspace(c)) /* skip leading white space */ + nptr++; + + if ((c = *nptr) == '+' || c == '-') { /* handle signs */ + negative = (c == '-'); + nptr++; + } + + if (base == 0) { /* determine base if unknown */ + base = 10; + if (*nptr == '0') { + base = 8; + nptr++; + if ((c = *nptr) == 'x' || c == 'X') { + base = 16; + nptr++; + } + } + } else if (base == 16 && *nptr == '0') { + /* discard 0x/0X prefix if hex */ + nptr++; + if ((c = *nptr == 'x') || c == 'X') + nptr++; + } + + limit = ULONG_MAX / base; /* ensure no overflow */ + + nptr--; /* convert the number */ + while ((c = *++nptr) != 0) { + if (isdigit(c)) + digit = c - '0'; + else if(isalpha(c)) + digit = c - (isupper(c) ? 'A' : 'a') + 10; + else + break; + if (digit < 0 || digit >= base) + break; + if (result > limit) + overflow = 1; + if (!overflow) { + result = base * result; + if (digit > ULONG_MAX - result) + overflow = 1; + else + result += digit; + } + } + if (negative && !overflow) /* BIZARRE, but ANSI says we should do this! */ + result = 0L - result; + if (overflow) { + //extern int errno; + //errno = ERANGE; + result = ULONG_MAX; + } + + if (endptr != NULL) /* point at tail */ + *endptr = (char *)nptr; + return result; +} + diff --git a/resources/project/lib/strtoupp.c b/resources/project/lib/strtoupp.c new file mode 100644 index 0000000..6177fb5 --- /dev/null +++ b/resources/project/lib/strtoupp.c @@ -0,0 +1,8 @@ +void +strtoupper(char *p) +{ + if(!p) + return; + for (; *p; p++) + *p = toupper (*p); +} diff --git a/resources/project/lib/testchar.c b/resources/project/lib/testchar.c new file mode 100644 index 0000000..924f3e0 --- /dev/null +++ b/resources/project/lib/testchar.c @@ -0,0 +1,4 @@ +int testchar() +{ +return *(volatile char *)(SERIAL+1); +} diff --git a/resources/project/lib/time.c b/resources/project/lib/time.c new file mode 100644 index 0000000..7b34961 --- /dev/null +++ b/resources/project/lib/time.c @@ -0,0 +1,55 @@ +#include + +unsigned long _get_count() +{ + unsigned long _contval; + asm volatile( + "lui $25, 0xbfb0\n\t" + "lw %0,-0x2000($25)\n\t" + :"=r"(_contval) + : + :"$25" + ); + return _contval; +} + +unsigned long get_count() +{ + return _get_count(); +} + +unsigned long clock_gettime(int sel,struct timespec *tmp) +{ + unsigned long n = 0; + n = _get_count(); + tmp->tv_nsec = n*(NSEC_PER_USEC/CPU_COUNT_PER_US)%NSEC_PER_USEC; + tmp->tv_usec = (n/CPU_COUNT_PER_US)%USEC_PER_MSEC; + tmp->tv_msec = (n/CPU_COUNT_PER_US/USEC_PER_MSEC)%MSEC_PER_SEC; + tmp->tv_sec = n/CPU_COUNT_PER_US/NSEC_PER_SEC; + printf("clock ns=%d,sec=%d\n",tmp->tv_nsec,tmp->tv_sec); + return 0; +} + +unsigned long get_clock() +{ + unsigned long n=0; + n=_get_count(); + return n; +} + +unsigned long get_ns(void) +{ + unsigned long n=0; + n = _get_count(); + n=n*(NSEC_PER_USEC/CPU_COUNT_PER_US); + return n; +} + + +unsigned long get_us(void) +{ + unsigned long n=0; + n = _get_count(); + n=n/CPU_COUNT_PER_US; + return n; +} diff --git a/resources/project/lib/toupper.c b/resources/project/lib/toupper.c new file mode 100644 index 0000000..faf2c5e --- /dev/null +++ b/resources/project/lib/toupper.c @@ -0,0 +1,8 @@ +int +toupper(int c) +{ +if(c>='a' && c<='z') + return c-'a'+'A'; +else + return c; +} diff --git a/resources/project/lib/udelay.c b/resources/project/lib/udelay.c new file mode 100644 index 0000000..9bdf5ca --- /dev/null +++ b/resources/project/lib/udelay.c @@ -0,0 +1,11 @@ +void udelay(int us) +{ +int count0,count1; +int debug=0; +us *=CPU_COUNT_PER_US; +asm volatile("mfc0 %0,$9":"=r"(count0)); +do{ +asm volatile("mfc0 %0,$9":"=r"(count1)); +}while(count1 -count0= '1' && *s <= '9') { + for (t = s; isdigit (*s); s++); + strncpy (tmp, t, s - t); + tmp[s - t] = '\0'; + atob (&n, tmp, 10); + if (haddot) + trunc = n; + else + width = n; + s--; + } else if (*s == '.') + haddot = 1; + } + if (*s == '%') { + *d++ = '%'; + *d = 0; + } else if (*s == 's') { + p = va_arg (ap, char *); + + if (p) + strcpy (d, p); + else + strcpy (d, "(null)"); + } else if (*s == 'c') { + n = va_arg (ap, int); + *d = n; + d[1] = 0; + } else { + if (*s == 'l') { + if (*++s == 'l') { + longlong = 1; + ++s; + } + } + if (strchr ("dobpxXu", *s)) { + if (*s == 'd') + base = -10; + else if (*s == 'u') + base = 10; + else if (*s == 'x' || *s == 'X') + base = 16; + else if(*s == 'p') { + base = 16; + *d++ = '0'; + *d++ = 'x'; + fmt = FMT_RJUST0; + width = 8; + } + else if (*s == 'o') + base = 8; + else if (*s == 'b') + base = 2; +#ifdef HAVE_QUAD + if (longlong) + llbtoa(d, va_arg (ap, quad_t), + base); +#else + if (longlong) + { + long x=va_arg (ap, long long); + btoa(d, (long)x, + base); + } + +#endif + else + btoa(d, va_arg (ap, int), base); + + if (*s == 'X') + strtoupper(d); + } +#ifdef FLOATINGPT + else if (strchr ("eEfgG", *s)) { + dbl = va_arg(ap, double); + dtoa (d, dbl, *s, width, trunc); + trunc = 0; + } +#endif + } + if (trunc) + d[trunc] = 0; + if (width) + str_fmt (d, width, fmt); + for (; *d; d++); + s++; + } else + *d++ = *s++; + } + *d = 0; + return (d - dst); +} + +#ifdef FLOATINGPT +/* + * Floating point output, cvt() onward lifted from BSD sources: + * + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#define to_char(n) ((n) + '0') +#define to_digit(c) ((c) - '0') +#define _isNan(arg) ((arg) != (arg)) + +static int cvt (rtype arg, int prec, char *signp, int fmtch, + char *startp, char *endp); +static char *round (double fract, int *exp, char *start, char *end, + char ch, char *signp); +static char *exponent(char *p, int exp, int fmtch); + + +/* + * _finite arg not Infinity or Nan + */ +static int _finite(rtype d) +{ +#if ENDIAN == ENDIAN_LITTLE + struct IEEEdp { + unsigned manl:32; + unsigned manh:20; + unsigned exp:11; + unsigned sign:1; + } *ip; +#else + struct IEEEdp { + unsigned sign:1; + unsigned exp:11; + unsigned manh:20; + unsigned manl:32; + } *ip; +#endif + + ip = (struct IEEEdp *)&d; + return (ip->exp != 0x7ff); +} + + +static void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec) +{ + char buf[MAX_FCONVERSION+1], *cp; + char sign; + int size; + + if( !_finite(arg) ) { + if( _isNan(arg) ) + strcpy (dbuf, "NaN"); + else if( arg < 0) + strcpy (dbuf, "-Infinity"); + else + strcpy (dbuf, "Infinity"); + return; + } + + if (prec == 0) + prec = 6; + else if (prec > MAX_FRACT) + prec = MAX_FRACT; + + /* leave room for sign at start of buffer */ + cp = buf + 1; + + /* + * cvt may have to round up before the "start" of + * its buffer, i.e. ``intf("%.2f", (double)9.999);''; + * if the first character is still NUL, it did. + * softsign avoids negative 0 if _double < 0 but + * no significant digits will be shown. + */ + *cp = '\0'; + size = cvt (arg, prec, &sign, fmtch, cp, buf + sizeof(buf)); + if (*cp == '\0') + cp++; + + if (sign) + *--cp = sign, size++; + + cp[size] = 0; + memcpy (dbuf, cp, size + 1); +} + + +static int +cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) +{ + register char *p, *t; + register double fract; + double integer, tmp; + int dotrim, expcnt, gformat; + + dotrim = expcnt = gformat = 0; + if (number < 0) { + number = -number; + *signp = '-'; + } else + *signp = 0; + + fract = modf(number, &integer); + + /* get an extra slot for rounding. */ + t = ++startp; + + /* + * get integer portion of number; put into the end of the buffer; the + * .01 is added for modf(356.0 / 10, &integer) returning .59999999... + */ + for (p = endp - 1; integer; ++expcnt) { + tmp = modf(integer / 10, &integer); + *p-- = to_char((int)((tmp + .01) * 10)); + } + switch (fmtch) { + case 'f': + /* reverse integer into beginning of buffer */ + if (expcnt) + for (; ++p < endp; *t++ = *p); + else + *t++ = '0'; + /* + * if precision required or alternate flag set, add in a + * decimal point. + */ + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = round(fract, (int *)NULL, startp, + t - 1, (char)0, signp); + } + for (; prec--; *t++ = '0'); + break; + case 'e': + case 'E': +eformat: if (expcnt) { + *t++ = *++p; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + /* if requires more precision and some integer left */ + for (; prec && ++p < endp; --prec) + *t++ = *p; + /* + * if done precision and more of the integer component, + * round using it; adjust fract so we don't re-round + * later. + */ + if (!prec && ++p < endp) { + fract = 0; + startp = round((double)0, &expcnt, startp, + t - 1, *p, signp); + } + /* adjust expcnt for digit in front of decimal */ + --expcnt; + } + /* until first fractional digit, decrement exponent */ + else if (fract) { + /* adjust expcnt for digit in front of decimal */ + for (expcnt = -1;; --expcnt) { + fract = modf(fract * 10, &tmp); + if (tmp) + break; + } + *t++ = to_char((int)tmp); + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + } + else { + *t++ = '0'; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + } + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = round(fract, &expcnt, startp, + t - 1, (char)0, signp); + } + /* if requires more precision */ + for (; prec--; *t++ = '0'); + + /* unless alternate flag, trim any g/G format trailing 0's */ + if (gformat && !TESTFLAG(ALTERNATE_FORM)) { + while (t > startp && *--t == '0'); + if (*t == '.') + --t; + ++t; + } + t = exponent(t, expcnt, fmtch); + break; + case 'g': + case 'G': + /* a precision of 0 is treated as a precision of 1. */ + if (!prec) + ++prec; + /* + * ``The style used depends on the value converted; style e + * will be used only if the exponent resulting from the + * conversion is less than -4 or greater than the precision.'' + * -- ANSI X3J11 + */ + if (expcnt > prec || (!expcnt && fract && fract < .0001)) { + /* + * g/G format counts "significant digits, not digits of + * precision; for the e/E format, this just causes an + * off-by-one problem, i.e. g/G considers the digit + * before the decimal point significant and e/E doesn't + * count it as precision. + */ + --prec; + fmtch -= 2; /* G->E, g->e */ + gformat = 1; + goto eformat; + } + /* + * reverse integer into beginning of buffer, + * note, decrement precision + */ + if (expcnt) + for (; ++p < endp; *t++ = *p, --prec); + else + *t++ = '0'; + /* + * if precision required or alternate flag set, add in a + * decimal point. If no digits yet, add in leading 0. + */ + if (prec || TESTFLAG(ALTERNATE_FORM)) { + dotrim = 1; + *t++ = '.'; + } + else + dotrim = 0; + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) { + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while(!tmp && !expcnt); + while (--prec && fract) { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } + } + if (fract) + startp = round(fract, (int *)NULL, startp, + t - 1, (char)0, signp); + } + /* alternate format, adds 0's for precision, else trim 0's */ + if (TESTFLAG(ALTERNATE_FORM)) + for (; prec--; *t++ = '0'); + else if (dotrim) { + while (t > startp && *--t == '0'); + if (*t != '.') + ++t; + } + } + return (t - startp); +} + + +static char * +round(double fract, int *exp, char *start, char *end, char ch, char *signp) +{ + double tmp; + + if (fract) + (void)modf(fract * 10, &tmp); + else + tmp = to_digit(ch); + if (tmp > 4) + for (;; --end) { + if (*end == '.') + --end; + if (++*end <= '9') + break; + *end = '0'; + if (end == start) { + if (exp) { /* e/E; increment exponent */ + *end = '1'; + ++*exp; + } + else { /* f; add extra digit */ + *--end = '1'; + --start; + } + break; + } + } + /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ + else if (*signp == '-') + for (;; --end) { + if (*end == '.') + --end; + if (*end != '0') + break; + if (end == start) + *signp = 0; + } + return (start); +} + +static char * +exponent(char *p, int exp, int fmtch) +{ + char *t; + char expbuf[MAX_FCONVERSION]; + + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAX_FCONVERSION; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++); + } + else { + *p++ = '0'; + *p++ = to_char(exp); + } + return (p); +} +#endif /* FLOATINGPT */ diff --git a/resources/project/src/Makefile b/resources/project/src/Makefile new file mode 100644 index 0000000..295979d --- /dev/null +++ b/resources/project/src/Makefile @@ -0,0 +1,24 @@ +CC = ${CROSS_COMPILE}gcc +LD = ${CROSS_COMPILE}ld +OBJCOPY = ${CROSS_COMPILE}objcopy +OBJDUMP = ${CROSS_COMPILE}objdump +AR = ${CROSS_COMPILE}ar + +AFLAGS = -G 0 -fno-pic -pipe -mno-abicalls -EL -mips1 +CFLAGS += -funroll-all-loops -falign-jumps=16 -falign-functions=16 -fgcse-sm -fgcse-las -finline-functions -finline-limit=1000 +CFLAGS += -G8 -I ../include +CFLAGS += -static + +SRCS = xxx.c +HEADERS = xxx.h + +.PHONY:compile link clean + +all: compile + echo "job done" + +compile: $(OPATH) $(SRCS) $(HEADERS) + $(CC) $(CFLAGS) -c $(SRCS) + +clean: + rm -rf *.o diff --git a/resources/project/start.S b/resources/project/start.S new file mode 100644 index 0000000..a27973b --- /dev/null +++ b/resources/project/start.S @@ -0,0 +1,69 @@ +#/* $Id: start.S,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */ + +/* + * Copyright (c) 2001 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB, Sweden. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef _KERNEL +#define _KERNEL +#endif + +#include +#include +#include +#include +#include +#include +#include + + .set noreorder + .globl _start + .globl start + .globl __main +_start: +start: + disable_trace_cmp_s + disable_num_monitor_s + + lui t2,0x0040 + mtc0 t2, c0_status + mtc0 zero, c0_cause + la sp, _stack + la gp, _gp + + la t1, memory_game ##### + li t2, 0x20000000 ### + subu t9, t1, t2 #kseg1 -> kseg0 + jr t9 ### + nop ##### + + .org 0x380 +1: b 1b + nop