2008-06-09 Ken Werner <ken.werner@de.ibm.com>
* libc/machine/spu/Makefile.am: Add new files.
	* libc/machine/spu/Makefile.in: Likewise.
	* libc/machine/spu/include/spu_timer.h: New file to add timer support
        using interrupts.
	* libc/machine/spu/spu_clock_stop.c: Likewise.
	* libc/machine/spu/spu_clock_svcs.c: Likewise.
	* libc/machine/spu/spu_timer_flih.S: Likewise.
	* libc/machine/spu/spu_timer_free.c: Likewise.
	* libc/machine/spu/spu_timer_internal.h: Likewise.
	* libc/machine/spu/spu_timer_slih.c: Likewise.
	* libc/machine/spu/spu_timer_slih_reg.c: Likewise.
	* libc/machine/spu/spu_timer_stop.c: Likewise.
	* libc/machine/spu/spu_timer_svcs.c: Likewise.
			
			
This commit is contained in:
		| @@ -1,3 +1,19 @@ | |||||||
|  | 2008-06-09  Ken Werner  <ken.werner@de.ibm.com> | ||||||
|  |  | ||||||
|  | 	* libc/machine/spu/Makefile.am: Add new files. | ||||||
|  | 	* libc/machine/spu/Makefile.in: Likewise. | ||||||
|  | 	* libc/machine/spu/include/spu_timer.h: New file to add timer support | ||||||
|  |         using interrupts. | ||||||
|  | 	* libc/machine/spu/spu_clock_stop.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_clock_svcs.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_flih.S: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_free.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_internal.h: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_slih.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_slih_reg.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_stop.c: Likewise. | ||||||
|  | 	* libc/machine/spu/spu_timer_svcs.c: Likewise. | ||||||
|  |  | ||||||
| 2008-06-09  Ken Werner  <ken.werner@de.ibm.com> | 2008-06-09  Ken Werner  <ken.werner@de.ibm.com> | ||||||
|  |  | ||||||
| 	* libc/machine/spu/strcat.c: Return value fixed. | 	* libc/machine/spu/strcat.c: Return value fixed. | ||||||
|   | |||||||
| @@ -21,7 +21,9 @@ lib_a_SOURCES = setjmp.S assert.c clearerr.c creat.c fclose.c feof.c \ | |||||||
| 	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \ | 	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \ | ||||||
| 	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \ | 	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \ | ||||||
| 	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c \ | 	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c \ | ||||||
| 	stack_reg_va.S | 	stack_reg_va.S spu_clock_svcs.c spu_clock_stop.c spu_timer_flih.S \ | ||||||
|  | 	spu_timer_slih.c spu_timer_slih_reg.c spu_timer_svcs.c \ | ||||||
|  | 	spu_timer_stop.c spu_timer_free.c | ||||||
|  |  | ||||||
| lib_a_CCASFLAGS = $(AM_CCASFLAGS) | lib_a_CCASFLAGS = $(AM_CCASFLAGS) | ||||||
| lib_a_CFLAGS = $(AM_CFLAGS) | lib_a_CFLAGS = $(AM_CFLAGS) | ||||||
|   | |||||||
| @@ -74,7 +74,11 @@ DIST_COMMON = $(srcdir)/../../../../config.guess \ | |||||||
| 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
| 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
| 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
| 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
|  | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
|  | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
|  | 	$(srcdir)/../../../../compile $(srcdir)/../../../../compile \ | ||||||
|  | 	$(srcdir)/../../../../compile | ||||||
| subdir = . | subdir = . | ||||||
| ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||||||
| am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \ | am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \ | ||||||
| @@ -131,7 +135,12 @@ am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-assert.$(OBJEXT) \ | |||||||
| 	lib_a-vscanf.$(OBJEXT) lib_a-vsiprintf.$(OBJEXT) \ | 	lib_a-vscanf.$(OBJEXT) lib_a-vsiprintf.$(OBJEXT) \ | ||||||
| 	lib_a-vsiscanf.$(OBJEXT) lib_a-vsniprintf.$(OBJEXT) \ | 	lib_a-vsiscanf.$(OBJEXT) lib_a-vsniprintf.$(OBJEXT) \ | ||||||
| 	lib_a-vsnprintf.$(OBJEXT) lib_a-vsprintf.$(OBJEXT) \ | 	lib_a-vsnprintf.$(OBJEXT) lib_a-vsprintf.$(OBJEXT) \ | ||||||
| 	lib_a-vsscanf.$(OBJEXT) lib_a-stack_reg_va.$(OBJEXT) | 	lib_a-vsscanf.$(OBJEXT) lib_a-stack_reg_va.$(OBJEXT) \ | ||||||
|  | 	lib_a-spu_clock_svcs.$(OBJEXT) lib_a-spu_clock_stop.$(OBJEXT) \ | ||||||
|  | 	lib_a-spu_timer_flih.$(OBJEXT) lib_a-spu_timer_slih.$(OBJEXT) \ | ||||||
|  | 	lib_a-spu_timer_slih_reg.$(OBJEXT) \ | ||||||
|  | 	lib_a-spu_timer_svcs.$(OBJEXT) lib_a-spu_timer_stop.$(OBJEXT) \ | ||||||
|  | 	lib_a-spu_timer_free.$(OBJEXT) | ||||||
| lib_a_OBJECTS = $(am_lib_a_OBJECTS) | lib_a_OBJECTS = $(am_lib_a_OBJECTS) | ||||||
| DEFAULT_INCLUDES = -I. -I$(srcdir) | DEFAULT_INCLUDES = -I. -I$(srcdir) | ||||||
| depcomp = | depcomp = | ||||||
| @@ -205,6 +214,11 @@ STRIP = @STRIP@ | |||||||
| USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@ | USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@ | ||||||
| USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@ | USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@ | ||||||
| VERSION = @VERSION@ | VERSION = @VERSION@ | ||||||
|  | ac_ct_AR = @ac_ct_AR@ | ||||||
|  | ac_ct_AS = @ac_ct_AS@ | ||||||
|  | ac_ct_RANLIB = @ac_ct_RANLIB@ | ||||||
|  | ac_ct_READELF = @ac_ct_READELF@ | ||||||
|  | ac_ct_STRIP = @ac_ct_STRIP@ | ||||||
| aext = @aext@ | aext = @aext@ | ||||||
| am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ | am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ | ||||||
| am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ | am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ | ||||||
| @@ -220,23 +234,18 @@ build_cpu = @build_cpu@ | |||||||
| build_os = @build_os@ | build_os = @build_os@ | ||||||
| build_vendor = @build_vendor@ | build_vendor = @build_vendor@ | ||||||
| datadir = @datadir@ | datadir = @datadir@ | ||||||
| datarootdir = @datarootdir@ |  | ||||||
| docdir = @docdir@ |  | ||||||
| dvidir = @dvidir@ |  | ||||||
| exec_prefix = @exec_prefix@ | exec_prefix = @exec_prefix@ | ||||||
| host = @host@ | host = @host@ | ||||||
| host_alias = @host_alias@ | host_alias = @host_alias@ | ||||||
| host_cpu = @host_cpu@ | host_cpu = @host_cpu@ | ||||||
| host_os = @host_os@ | host_os = @host_os@ | ||||||
| host_vendor = @host_vendor@ | host_vendor = @host_vendor@ | ||||||
| htmldir = @htmldir@ |  | ||||||
| includedir = @includedir@ | includedir = @includedir@ | ||||||
| infodir = @infodir@ | infodir = @infodir@ | ||||||
| install_sh = @install_sh@ | install_sh = @install_sh@ | ||||||
| libdir = @libdir@ | libdir = @libdir@ | ||||||
| libexecdir = @libexecdir@ | libexecdir = @libexecdir@ | ||||||
| libm_machine_dir = @libm_machine_dir@ | libm_machine_dir = @libm_machine_dir@ | ||||||
| localedir = @localedir@ |  | ||||||
| localstatedir = @localstatedir@ | localstatedir = @localstatedir@ | ||||||
| lpfx = @lpfx@ | lpfx = @lpfx@ | ||||||
| machine_dir = @machine_dir@ | machine_dir = @machine_dir@ | ||||||
| @@ -245,10 +254,8 @@ mkdir_p = @mkdir_p@ | |||||||
| newlib_basedir = @newlib_basedir@ | newlib_basedir = @newlib_basedir@ | ||||||
| oext = @oext@ | oext = @oext@ | ||||||
| oldincludedir = @oldincludedir@ | oldincludedir = @oldincludedir@ | ||||||
| pdfdir = @pdfdir@ |  | ||||||
| prefix = @prefix@ | prefix = @prefix@ | ||||||
| program_transform_name = @program_transform_name@ | program_transform_name = @program_transform_name@ | ||||||
| psdir = @psdir@ |  | ||||||
| sbindir = @sbindir@ | sbindir = @sbindir@ | ||||||
| sharedstatedir = @sharedstatedir@ | sharedstatedir = @sharedstatedir@ | ||||||
| sys_dir = @sys_dir@ | sys_dir = @sys_dir@ | ||||||
| @@ -271,7 +278,9 @@ lib_a_SOURCES = setjmp.S assert.c clearerr.c creat.c fclose.c feof.c \ | |||||||
| 	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \ | 	tmpnam.c ungetc.c usleep.c vfiprintf.c vfiscanf.c vfprintf.c \ | ||||||
| 	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \ | 	vfscanf.c viprintf.c viscanf.c vprintf.c vscanf.c vsiprintf.c \ | ||||||
| 	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c \ | 	vsiscanf.c vsniprintf.c vsnprintf.c vsprintf.c vsscanf.c \ | ||||||
| 	stack_reg_va.S | 	stack_reg_va.S spu_clock_svcs.c spu_clock_stop.c spu_timer_flih.S \ | ||||||
|  | 	spu_timer_slih.c spu_timer_slih_reg.c spu_timer_svcs.c \ | ||||||
|  | 	spu_timer_stop.c spu_timer_free.c | ||||||
|  |  | ||||||
| lib_a_CCASFLAGS = $(AM_CCASFLAGS) | lib_a_CCASFLAGS = $(AM_CCASFLAGS) | ||||||
| lib_a_CFLAGS = $(AM_CFLAGS) | lib_a_CFLAGS = $(AM_CFLAGS) | ||||||
| @@ -430,6 +439,12 @@ lib_a-stack_reg_va.o: stack_reg_va.S | |||||||
| lib_a-stack_reg_va.obj: stack_reg_va.S | lib_a-stack_reg_va.obj: stack_reg_va.S | ||||||
| 	$(CCAS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-stack_reg_va.obj `if test -f 'stack_reg_va.S'; then $(CYGPATH_W) 'stack_reg_va.S'; else $(CYGPATH_W) '$(srcdir)/stack_reg_va.S'; fi` | 	$(CCAS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-stack_reg_va.obj `if test -f 'stack_reg_va.S'; then $(CYGPATH_W) 'stack_reg_va.S'; else $(CYGPATH_W) '$(srcdir)/stack_reg_va.S'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_flih.o: spu_timer_flih.S | ||||||
|  | 	$(CCAS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-spu_timer_flih.o `test -f 'spu_timer_flih.S' || echo '$(srcdir)/'`spu_timer_flih.S | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_flih.obj: spu_timer_flih.S | ||||||
|  | 	$(CCAS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-spu_timer_flih.obj `if test -f 'spu_timer_flih.S'; then $(CYGPATH_W) 'spu_timer_flih.S'; else $(CYGPATH_W) '$(srcdir)/spu_timer_flih.S'; fi` | ||||||
|  |  | ||||||
| .c.o: | .c.o: | ||||||
| 	$(COMPILE) -c $< | 	$(COMPILE) -c $< | ||||||
|  |  | ||||||
| @@ -855,6 +870,48 @@ lib_a-vsscanf.o: vsscanf.c | |||||||
|  |  | ||||||
| lib_a-vsscanf.obj: vsscanf.c | lib_a-vsscanf.obj: vsscanf.c | ||||||
| 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vsscanf.obj `if test -f 'vsscanf.c'; then $(CYGPATH_W) 'vsscanf.c'; else $(CYGPATH_W) '$(srcdir)/vsscanf.c'; fi` | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vsscanf.obj `if test -f 'vsscanf.c'; then $(CYGPATH_W) 'vsscanf.c'; else $(CYGPATH_W) '$(srcdir)/vsscanf.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_clock_svcs.o: spu_clock_svcs.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_clock_svcs.o `test -f 'spu_clock_svcs.c' || echo '$(srcdir)/'`spu_clock_svcs.c | ||||||
|  |  | ||||||
|  | lib_a-spu_clock_svcs.obj: spu_clock_svcs.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_clock_svcs.obj `if test -f 'spu_clock_svcs.c'; then $(CYGPATH_W) 'spu_clock_svcs.c'; else $(CYGPATH_W) '$(srcdir)/spu_clock_svcs.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_clock_stop.o: spu_clock_stop.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_clock_stop.o `test -f 'spu_clock_stop.c' || echo '$(srcdir)/'`spu_clock_stop.c | ||||||
|  |  | ||||||
|  | lib_a-spu_clock_stop.obj: spu_clock_stop.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_clock_stop.obj `if test -f 'spu_clock_stop.c'; then $(CYGPATH_W) 'spu_clock_stop.c'; else $(CYGPATH_W) '$(srcdir)/spu_clock_stop.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_slih.o: spu_timer_slih.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_slih.o `test -f 'spu_timer_slih.c' || echo '$(srcdir)/'`spu_timer_slih.c | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_slih.obj: spu_timer_slih.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_slih.obj `if test -f 'spu_timer_slih.c'; then $(CYGPATH_W) 'spu_timer_slih.c'; else $(CYGPATH_W) '$(srcdir)/spu_timer_slih.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_slih_reg.o: spu_timer_slih_reg.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_slih_reg.o `test -f 'spu_timer_slih_reg.c' || echo '$(srcdir)/'`spu_timer_slih_reg.c | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_slih_reg.obj: spu_timer_slih_reg.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_slih_reg.obj `if test -f 'spu_timer_slih_reg.c'; then $(CYGPATH_W) 'spu_timer_slih_reg.c'; else $(CYGPATH_W) '$(srcdir)/spu_timer_slih_reg.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_svcs.o: spu_timer_svcs.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_svcs.o `test -f 'spu_timer_svcs.c' || echo '$(srcdir)/'`spu_timer_svcs.c | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_svcs.obj: spu_timer_svcs.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_svcs.obj `if test -f 'spu_timer_svcs.c'; then $(CYGPATH_W) 'spu_timer_svcs.c'; else $(CYGPATH_W) '$(srcdir)/spu_timer_svcs.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_stop.o: spu_timer_stop.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_stop.o `test -f 'spu_timer_stop.c' || echo '$(srcdir)/'`spu_timer_stop.c | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_stop.obj: spu_timer_stop.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_stop.obj `if test -f 'spu_timer_stop.c'; then $(CYGPATH_W) 'spu_timer_stop.c'; else $(CYGPATH_W) '$(srcdir)/spu_timer_stop.c'; fi` | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_free.o: spu_timer_free.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_free.o `test -f 'spu_timer_free.c' || echo '$(srcdir)/'`spu_timer_free.c | ||||||
|  |  | ||||||
|  | lib_a-spu_timer_free.obj: spu_timer_free.c | ||||||
|  | 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-spu_timer_free.obj `if test -f 'spu_timer_free.c'; then $(CYGPATH_W) 'spu_timer_free.c'; else $(CYGPATH_W) '$(srcdir)/spu_timer_free.c'; fi` | ||||||
| uninstall-info-am: | uninstall-info-am: | ||||||
|  |  | ||||||
| ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||||||
|   | |||||||
							
								
								
									
										84
									
								
								newlib/libc/machine/spu/include/spu_timer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								newlib/libc/machine/spu/include/spu_timer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | #ifndef _SPU_TIMER_H_ | ||||||
|  | #define _SPU_TIMER_H_ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
|  |  | ||||||
|  | /* Clock services.  */ | ||||||
|  | extern void spu_clock_start (void); | ||||||
|  | extern int spu_clock_stop (void); | ||||||
|  | extern uint64_t spu_clock_read (void); | ||||||
|  |  | ||||||
|  | /* Timer services.  */ | ||||||
|  | extern int spu_timer_alloc (int interval, void (*func) (int)); | ||||||
|  | extern int spu_timer_free (int id); | ||||||
|  | extern int spu_timer_start (int id); | ||||||
|  | extern int spu_timer_stop (int id); | ||||||
|  |  | ||||||
|  | /* Interrupt services.  */ | ||||||
|  | extern void spu_slih_register (unsigned event_mask, | ||||||
|  | 			       unsigned (*slih) (unsigned)); | ||||||
|  | extern unsigned spu_clock_slih (unsigned event_mask); | ||||||
|  |  | ||||||
|  | /* Number of supported timers.  */ | ||||||
|  | #define SPU_TIMER_NTIMERS               4 | ||||||
|  |  | ||||||
|  | /* Recommended minimun spu timer interval time from (cat /proc/cpuinfo) | ||||||
|  |     * QS20       100/14318000  = 6.98 usec | ||||||
|  |     * QS21/QS22  100/26666666  = 3.75 usec | ||||||
|  |     * PS3        100/79800000  = 1.25 usec  */ | ||||||
|  | #define SPU_TIMER_MIN_INTERVAL          100 | ||||||
|  |  | ||||||
|  | /* Clock error codes.  */ | ||||||
|  | #define SPU_CLOCK_ERR_NOT_RUNNING       -2 | ||||||
|  | #define SPU_CLOCK_ERR_STILL_RUNNING     -3 | ||||||
|  | #define SPU_CLOCK_ERR_TIMERS_ACTIVE     -4 | ||||||
|  |  | ||||||
|  | /* Timer error codes.  */ | ||||||
|  | #define SPU_TIMER_ERR_INVALID_PARM      -10 | ||||||
|  | #define SPU_TIMER_ERR_NONE_FREE         -11 | ||||||
|  | #define SPU_TIMER_ERR_INVALID_ID        -12 | ||||||
|  | #define SPU_TIMER_ERR_ACTIVE            -13 | ||||||
|  | #define SPU_TIMER_ERR_NOT_ACTIVE        -14 | ||||||
|  | #define SPU_TIMER_ERR_NOCLOCK           -15 | ||||||
|  | #define SPU_TIMER_ERR_FREE              -16 | ||||||
|  | #define SPU_TIMER_ERR_NOT_STOPPED       -17 | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										67
									
								
								newlib/libc/machine/spu/spu_clock_stop.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								newlib/libc/machine/spu/spu_clock_stop.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* SPU clock stop library service.  */ | ||||||
|  | #include <spu_timer.h> | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  |  | ||||||
|  | /* Stops the SPU clock: | ||||||
|  |     * decrements clock start count | ||||||
|  |     * when count is zero, disables the decrementer event and stops the | ||||||
|  |       decrementer | ||||||
|  |    Returns 0 on success and  <0 on failure: | ||||||
|  |     * SPU_CLOCK_ERR_NOT_RUNNING - clock was already off | ||||||
|  |     * SPU_CLOCK_ERR_TIMERS_ACTIVE - active timers exist | ||||||
|  |     * SPU_CLOCK_ERR_STILL_RUNNING - start count was decremented but clock was | ||||||
|  |       not stopped  */ | ||||||
|  | int | ||||||
|  | spu_clock_stop (void) | ||||||
|  | { | ||||||
|  |   if (__spu_clock_startcnt == 0) | ||||||
|  |     return SPU_CLOCK_ERR_NOT_RUNNING; | ||||||
|  |  | ||||||
|  |   if (__spu_clock_startcnt == 1 && (__spu_timers_active || __spu_timers_handled)) | ||||||
|  |     return SPU_CLOCK_ERR_TIMERS_ACTIVE; | ||||||
|  |  | ||||||
|  |   /* Don't stop clock if the clock is still in use.  */ | ||||||
|  |   if (--__spu_clock_startcnt != 0) | ||||||
|  |     return SPU_CLOCK_ERR_STILL_RUNNING; | ||||||
|  |  | ||||||
|  |   /* Clock stopped, stop decrementer.  */ | ||||||
|  |   __disable_spu_decr (); | ||||||
|  |  | ||||||
|  |   /* Clock is enabled on clock start - restore to original state (saved at start).  */ | ||||||
|  |   if (__likely (!__spu_clock_state_was_enabled)) | ||||||
|  |     { | ||||||
|  |       spu_idisable (); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
							
								
								
									
										93
									
								
								newlib/libc/machine/spu/spu_clock_svcs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								newlib/libc/machine/spu/spu_clock_svcs.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* SPU clock start and read library services.  */ | ||||||
|  | #include <spu_timer.h> | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  |  | ||||||
|  | /* The software managed timebase value.  */ | ||||||
|  | volatile uint64_t __spu_tb_val __attribute__ ((aligned (16))); | ||||||
|  |  | ||||||
|  | /* Timeout value of the current interval.  */ | ||||||
|  | volatile int __spu_tb_timeout __attribute__ ((aligned (16))); | ||||||
|  |  | ||||||
|  | /* Clock start count (clock is running if >0).  */ | ||||||
|  | volatile unsigned __spu_clock_startcnt __attribute__ ((aligned (16))); | ||||||
|  |  | ||||||
|  | /* Saved interrupt state from clock_start.  */ | ||||||
|  | volatile unsigned __spu_clock_state_was_enabled; | ||||||
|  |  | ||||||
|  | /* Initializes the software managed timebase, enables the decrementer event, | ||||||
|  |    starts the decrementer and enables interrupts. Must be called before | ||||||
|  |    clock or timer services can be used. Should only be called by base app/lib | ||||||
|  |    code (not from an interrupt/timer handler). | ||||||
|  |    Returns with interrupts ENABLED.  */ | ||||||
|  | void | ||||||
|  | spu_clock_start (void) | ||||||
|  | { | ||||||
|  |   /* Increment clock start and return if it was already running.  */ | ||||||
|  |   if (++__spu_clock_startcnt > 1) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   __spu_clock_state_was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |  | ||||||
|  |   spu_idisable (); | ||||||
|  |   __spu_tb_timeout = CLOCK_START_VALUE; | ||||||
|  |   __spu_tb_val = 0; | ||||||
|  |  | ||||||
|  |   /* Disable, write, enable the decrementer.  */ | ||||||
|  |   __enable_spu_decr (__spu_tb_timeout, __disable_spu_decr ()); | ||||||
|  |  | ||||||
|  |   spu_ienable (); | ||||||
|  |  | ||||||
|  |   return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Returns a monotonically increasing, 64-bit counter, in timebase units, | ||||||
|  |    relative to the last call to spu_clock_start().  */ | ||||||
|  | uint64_t | ||||||
|  | spu_clock_read (void) | ||||||
|  | { | ||||||
|  |   int64_t time; | ||||||
|  |   unsigned was_enabled; | ||||||
|  |  | ||||||
|  |   /* Return 0 if clock is off.  */ | ||||||
|  |   if (__spu_clock_startcnt == 0) | ||||||
|  |     return 0LL; | ||||||
|  |  | ||||||
|  |   was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |   spu_idisable (); | ||||||
|  |  | ||||||
|  |   time = __spu_tb_val + (__spu_tb_timeout - spu_readch (SPU_RdDec)); | ||||||
|  |  | ||||||
|  |   if (__likely (was_enabled)) | ||||||
|  |     spu_ienable (); | ||||||
|  |   return time; | ||||||
|  | } | ||||||
							
								
								
									
										152
									
								
								newlib/libc/machine/spu/spu_timer_flih.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								newlib/libc/machine/spu/spu_timer_flih.S
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /*  First-level interrupt handler.  */ | ||||||
|  |  | ||||||
|  | /* The following two convenience macros assist in the coding of the | ||||||
|  |    saving and restoring the volatile register starting from register | ||||||
|  |    2 up to register 79. | ||||||
|  |  | ||||||
|  |    saveregs     first, last    Saves registers from first to the last. | ||||||
|  |    restoreregs  first, last    Restores registers from last down to first. | ||||||
|  |  | ||||||
|  |    Note:       first must be less than or equal to last.  */ | ||||||
|  |  | ||||||
|  | .macro  saveregs        first, last | ||||||
|  | 	stqd            $\first, -(STACK_SKIP+\first)*16($SP) | ||||||
|  | .if     \last-\first | ||||||
|  | 	saveregs        "(\first+1)",\last | ||||||
|  | .endif | ||||||
|  | .endm | ||||||
|  |  | ||||||
|  |  | ||||||
|  | .macro  restoreregs     first, last | ||||||
|  | 	lqd             $\last, (82-\last)*16($SP) | ||||||
|  | .if     \last-\first | ||||||
|  | 	restoreregs     \first,"(\last-1)" | ||||||
|  | .endif | ||||||
|  | .endm | ||||||
|  |  | ||||||
|  | 	.section        .interrupt,"ax" | ||||||
|  | 	.align          3 | ||||||
|  | 	.type           spu_flih, @function | ||||||
|  | spu_flih: | ||||||
|  | 	/* Adjust the stack pointer to skip the maximum register save area | ||||||
|  | 	   (STACK_SKIP quadword registers) in case an interrupt occurred while | ||||||
|  | 	   executing a leaf function that used the stack area without actually | ||||||
|  | 	   allocating its own stack frame.  */ | ||||||
|  | 	.set            STACK_SKIP, 125 | ||||||
|  |  | ||||||
|  | 	/* Save the current link register on a new stack frame for the | ||||||
|  | 	   normal spu_flih() version of this file.  */ | ||||||
|  | 	stqd            $0,  -(STACK_SKIP+80)*16($SP) | ||||||
|  | 	stqd            $SP, -(STACK_SKIP+82)*16($SP)   /* Save back chain pointer.  */ | ||||||
|  |  | ||||||
|  | 	saveregs        2, 39 | ||||||
|  |  | ||||||
|  | 	il              $2,  -(STACK_SKIP+82)*16        /* Stack frame size.  */ | ||||||
|  | 	rdch            $3, $SPU_RdEventStat            /* Read event status.  */ | ||||||
|  |  | ||||||
|  | 	rdch            $6, $SPU_RdEventMask            /* Read event mask.  */ | ||||||
|  | 	hbrp                                            /* Open a slot for instruction prefetch.  */ | ||||||
|  |  | ||||||
|  | 	saveregs        40,59 | ||||||
|  |  | ||||||
|  | 	clz             $4, $3                          /* Get first slih index.  */ | ||||||
|  | 	stqd            $6,  -(STACK_SKIP+1)*16($SP)    /* Save event mask on stack.  */ | ||||||
|  |  | ||||||
|  | 	saveregs        60, 67 | ||||||
|  |  | ||||||
|  | 	/* Do not disable/ack the decrementer event here. | ||||||
|  | 	   The timer library manages this and expects it | ||||||
|  | 	   to be enabled upon entry to the SLIH. */ | ||||||
|  | 	il              $7, 0x20 | ||||||
|  | 	andc            $5, $3, $7 | ||||||
|  | 	andc            $7, $6, $5                      /* Clear event bits.  */ | ||||||
|  | 	saveregs        68, 69 | ||||||
|  |  | ||||||
|  | 	wrch            $SPU_WrEventAck, $3             /* Ack events(s) - include decrementer event.  */ | ||||||
|  | 	wrch            $SPU_WrEventMask, $7            /* Disable event(s) - exclude decrementer event.  */ | ||||||
|  |  | ||||||
|  | 	saveregs        70, 79 | ||||||
|  |  | ||||||
|  | 	a               $SP, $SP, $2                    /* Instantiate flih stack frame.  */ | ||||||
|  | next_event: | ||||||
|  | 	/* Fetch and dispatch the event handler for the first non-zero event. The | ||||||
|  | 	   dispatch handler is indexed into the __spu_slih_handlers array using the | ||||||
|  | 	   count of zero off the event status as an index.  */ | ||||||
|  | 	ila             $5, __spu_slih_handlers         /* Slih array offset.  */ | ||||||
|  |  | ||||||
|  | 	shli            $4, $4, 2                       /* Slih entry offset.  */ | ||||||
|  | 	lqx             $5, $4, $5                      /* Load slih address.  */ | ||||||
|  | 	rotqby          $5, $5, $4                      /* Rotate to word 0.  */ | ||||||
|  | 	bisl            $0, $5                          /* Branch to slih.  */ | ||||||
|  |  | ||||||
|  | 	clz             $4, $3                          /* Get next slih index.  */ | ||||||
|  | 	brnz            $3, next_event | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	lqd             $2, 81*16($SP)                  /* Read event mask from stack.  */ | ||||||
|  |  | ||||||
|  | 	restoreregs     40, 79 | ||||||
|  |  | ||||||
|  | 	wrch            $SPU_WrEventMask, $2            /* Restore event mask.  */ | ||||||
|  | 	hbrp                                            /* Open a slot for instruction pre-fetch.  */ | ||||||
|  |  | ||||||
|  | 	restoreregs     2, 39 | ||||||
|  |  | ||||||
|  | 	/* Restore the link register from the new stack frame for the | ||||||
|  | 	   normal spu_flih() version of this file.  */ | ||||||
|  | 	lqd             $0,  2*16($SP) | ||||||
|  |  | ||||||
|  | 	lqd             $SP, 0*16($SP)                 /* restore stack pointer from back chain ptr.  */ | ||||||
|  |  | ||||||
|  | 	irete                                          /* Return from interrupt and re-enable interrupts.  */ | ||||||
|  | 	.size           spu_flih, .-spu_flih | ||||||
|  | /* spu_slih_handlers[] | ||||||
|  |    Here we initialize 33 default event handlers.  The first entry in this array | ||||||
|  |    corresponds to the event handler for the event associated with bit 0 of | ||||||
|  |    Channel 0 (External Event Status).  The 32nd entry in this array corresponds | ||||||
|  |    to bit 31 of Channel 0 (DMA Tag Status Update Event).  The 33rd entry in | ||||||
|  |    this array is a special case entry to handle "phantom events" which occur | ||||||
|  |    when the channel count for Channel 0 is 1, causing an asynchronous SPU | ||||||
|  |    interrupt, but the value returned for a read of Channel 0 is 0.  The index | ||||||
|  |    calculated into this array by spu_flih() for this case is 32, hence the | ||||||
|  |    33rd entry.  */ | ||||||
|  | .data | ||||||
|  | 	.align  4 | ||||||
|  | 	.extern __spu_default_slih | ||||||
|  | 	.global __spu_slih_handlers | ||||||
|  | 	.type   __spu_slih_handlers, @object | ||||||
|  | __spu_slih_handlers: | ||||||
|  | 	.rept 33 | ||||||
|  | 	.long   __spu_default_slih | ||||||
|  | 	.endr | ||||||
|  | 	.size   __spu_slih_handlers, .-__spu_slih_handlers | ||||||
							
								
								
									
										86
									
								
								newlib/libc/machine/spu/spu_timer_free.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								newlib/libc/machine/spu/spu_timer_free.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* SPU timer free library service.  */ | ||||||
|  | #include <spu_timer.h> | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Frees an allocated timer. The timer must be in the stopped state for this | ||||||
|  |    to succeed. Maybe be called: | ||||||
|  |     * after allocated, before it's started | ||||||
|  |     * after it's been explicitly stopped | ||||||
|  |    Returns 0 on success, timer sucessfully deallocated. Returns <0 on failure | ||||||
|  |     * SPU_TIMER_INVALID_ID - id out of range | ||||||
|  |     * SPU_TIMER_ERR_FREE - id in free state | ||||||
|  |     * SPU_TIMER_ERR_ACTIVE - id in handled or active state  */ | ||||||
|  | int | ||||||
|  | spu_timer_free (int id) | ||||||
|  | { | ||||||
|  |   spu_timer_t *t, **pn; | ||||||
|  |   unsigned was_enabled; | ||||||
|  |  | ||||||
|  |   if (id < 0 || id >= SPU_TIMER_NTIMERS) | ||||||
|  |     return SPU_TIMER_ERR_INVALID_ID; | ||||||
|  |  | ||||||
|  |   if (__spu_timers[id].state == SPU_TIMER_STOPPED) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |       was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |       spu_idisable (); | ||||||
|  |  | ||||||
|  |       t = __spu_timers_stopped; | ||||||
|  |       pn = &__spu_timers_stopped; | ||||||
|  |  | ||||||
|  |       while (t && (t->id != id)) | ||||||
|  | 	{ | ||||||
|  | 	  pn = &t->next; | ||||||
|  | 	  t = t->next; | ||||||
|  | 	} | ||||||
|  | #ifdef SPU_TIMER_DEBUG | ||||||
|  |       if (!t) | ||||||
|  | 	ABORT (); | ||||||
|  | #endif | ||||||
|  |       *pn = t->next; | ||||||
|  |  | ||||||
|  |       /* Add timer back to free list (mask).  */ | ||||||
|  |       __spu_timers_avail |= (1 << (id)); | ||||||
|  |       __spu_timers[id].state = SPU_TIMER_FREE; | ||||||
|  |  | ||||||
|  |       if (__likely (was_enabled)) | ||||||
|  | 	spu_ienable (); | ||||||
|  |  | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* Handle invalid states.  */ | ||||||
|  |   return (__spu_timers[id].state == SPU_TIMER_FREE) ? | ||||||
|  | 	  SPU_TIMER_ERR_FREE : SPU_TIMER_ERR_ACTIVE; | ||||||
|  | } | ||||||
							
								
								
									
										140
									
								
								newlib/libc/machine/spu/spu_timer_internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								newlib/libc/machine/spu/spu_timer_internal.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* Internal definitions for SPU timer library.  */ | ||||||
|  | #ifndef _SPU_TIMER_INTERNAL_H_ | ||||||
|  | #define _SPU_TIMER_INTERNAL_H_ | ||||||
|  |  | ||||||
|  | #include <spu_intrinsics.h> | ||||||
|  | #include <spu_mfcio.h> | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #ifdef SPU_TIMER_DEBUG | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <assert.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /* The timer state tells which list its on.  */ | ||||||
|  | typedef enum spu_timer_state | ||||||
|  | { | ||||||
|  |   SPU_TIMER_FREE = 0, | ||||||
|  |   SPU_TIMER_ACTIVE = 1, | ||||||
|  |   SPU_TIMER_HANDLED = 2, | ||||||
|  |   SPU_TIMER_STOPPED = 3 | ||||||
|  | } spu_timer_state_t; | ||||||
|  |  | ||||||
|  | typedef struct spu_timer | ||||||
|  | { | ||||||
|  |   int tmout __attribute__ ((aligned (16)));	/* Time until expiration (tb).  */ | ||||||
|  |   int intvl __attribute__ ((aligned (16)));	/* Interval.  */ | ||||||
|  |   int id __attribute__ ((aligned (16))); | ||||||
|  |   spu_timer_state_t state __attribute__ ((aligned (16))); | ||||||
|  |   void (*func) (int) __attribute__ ((aligned (16)));	/* Handler.  */ | ||||||
|  |   struct spu_timer *next __attribute__ ((aligned (16))); | ||||||
|  | } spu_timer_t; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Max decrementer value.  */ | ||||||
|  | #define DECR_MAX        0xFFFFFFFFU | ||||||
|  |  | ||||||
|  |  /* Arbitrary non-triggering value.  */ | ||||||
|  | #define CLOCK_START_VALUE 0x7FFFFFFF | ||||||
|  |  | ||||||
|  | #define MIN_INTVL       1 | ||||||
|  | #define MAX_INTVL       INT_MAX | ||||||
|  |  | ||||||
|  | /* Timers within 15 tics will expire together.  */ | ||||||
|  | #define TIMER_INTERVAL_WINDOW  15 | ||||||
|  |  | ||||||
|  | /* Disables the decrementer and returns the saved event mask for a subsequent | ||||||
|  |    call to __enable_spu_decr. The decrementer interrupt is acknowledged in the | ||||||
|  |    flih when the event is received, but is required also as part of the | ||||||
|  |    procedure to stop the decrementer.  */ | ||||||
|  | static inline unsigned | ||||||
|  | __disable_spu_decr (void) | ||||||
|  | { | ||||||
|  |   unsigned mask = spu_readch (SPU_RdEventMask); | ||||||
|  |   spu_writech (SPU_WrEventMask, mask & ~MFC_DECREMENTER_EVENT); | ||||||
|  |   spu_writech (SPU_WrEventAck, MFC_DECREMENTER_EVENT); | ||||||
|  |   spu_sync_c (); | ||||||
|  |   return mask; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Writes and enables the decrementer, along with the given event mask.  */ | ||||||
|  | static inline void | ||||||
|  | __enable_spu_decr (int val, unsigned mask) | ||||||
|  | { | ||||||
|  |   spu_writech (SPU_WrDec, (val)); | ||||||
|  |   spu_writech (SPU_WrEventMask, mask | MFC_DECREMENTER_EVENT); | ||||||
|  |   spu_sync_c (); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* These are shared between modules but are not inlined, to save space.  */ | ||||||
|  | extern void __spu_timer_start (int id, int reset); | ||||||
|  | extern void __reset_spu_decr (int val); | ||||||
|  |  | ||||||
|  | /* The timers.  */ | ||||||
|  | extern spu_timer_t __spu_timers[]; | ||||||
|  |  | ||||||
|  | /* Active timer list.  */ | ||||||
|  | extern spu_timer_t *__spu_timers_active; | ||||||
|  |  | ||||||
|  | /* Stopped (allocated) timer list.  */ | ||||||
|  | extern spu_timer_t *__spu_timers_stopped; | ||||||
|  |  | ||||||
|  | /* List of timers being handled.  */ | ||||||
|  | extern spu_timer_t *__spu_timers_handled; | ||||||
|  |  | ||||||
|  | /* Bitmask of available timers.  */ | ||||||
|  | extern unsigned __spu_timers_avail; | ||||||
|  |  | ||||||
|  | /* The software managed timebase value.  */ | ||||||
|  | extern volatile uint64_t __spu_tb_val; | ||||||
|  |  | ||||||
|  | /* Timeout value of the current interval.  */ | ||||||
|  | extern volatile int __spu_tb_timeout; | ||||||
|  |  | ||||||
|  | /* Clock start count (clock is running if >0).  */ | ||||||
|  | extern volatile unsigned __spu_clock_startcnt; | ||||||
|  |  | ||||||
|  | /* Saved interrupt state from clock_start.  */ | ||||||
|  | extern volatile unsigned __spu_clock_state_was_enabled; | ||||||
|  |  | ||||||
|  | #define __likely(_c)        __builtin_expect((_c), 1) | ||||||
|  | #define __unlikely(_c)      __builtin_expect((_c), 0) | ||||||
|  |  | ||||||
|  | #define ABORT() \ | ||||||
|  | {\ | ||||||
|  |     fprintf(stderr, "Internal error, aborting: %s:%d\n", __FILE__, __LINE__);\ | ||||||
|  |     assert(0);\ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										221
									
								
								newlib/libc/machine/spu/spu_timer_slih.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								newlib/libc/machine/spu/spu_timer_slih.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* Second Level Interrupt handler and related services for SPU timers.  */ | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  | /* Resets decrementer to the specified value. Also updates software timebase | ||||||
|  |    to account for the time between the last decrementer reset and now. There | ||||||
|  |    are two cases: | ||||||
|  |     * Called by application to start a new timer. | ||||||
|  |     * Called by spu_clock to active the next timer. | ||||||
|  |    In both cases, the amount of time is the current interval timeout minus the | ||||||
|  |    current decrementer value.  */ | ||||||
|  | void | ||||||
|  | __reset_spu_decr (int val) | ||||||
|  | { | ||||||
|  |  | ||||||
|  |   /* The interrupt occurs when the msb goes from 0 to 1 or when the decrementer | ||||||
|  |      goes from 0 to -1.  To be precisely accurate we should set the timer to | ||||||
|  |      the intverval -1, unless the interval passed in is 0 in which case it | ||||||
|  |      should be left at 0.  */ | ||||||
|  |   int enable_val = (__likely (val)) ? val - 1 : 0; | ||||||
|  |  | ||||||
|  |   /* Decrementer must be stopped before writing it - minimize the time | ||||||
|  |      stopped.  */ | ||||||
|  |   unsigned mask = __disable_spu_decr (); | ||||||
|  |  | ||||||
|  |   /* Perform tb correction before resettting the decrementer. the corrected | ||||||
|  |      value is the current timeout value minus the current decrementer value. | ||||||
|  |      Occasionally the read returns 0 - a second read will clear this | ||||||
|  |      condition.  */ | ||||||
|  |   int decval0 = spu_readch (SPU_RdDec); | ||||||
|  |   int decval = spu_readch (SPU_RdDec); | ||||||
|  |   /* Restart decrementer with next timeout val.  */ | ||||||
|  |   __enable_spu_decr (enable_val, mask); | ||||||
|  |  | ||||||
|  |   /* Update the timebase values before enabling for interrupts.  */ | ||||||
|  |   __spu_tb_val += __spu_tb_timeout - decval; | ||||||
|  |   __spu_tb_timeout = enable_val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Update software timebase and timeout value for the 'next to expire' timer. | ||||||
|  |    Called when starting a new timer so the timer list will have timeouts | ||||||
|  |    relative to the current time.  */ | ||||||
|  | static inline void | ||||||
|  | __update_spu_tb_val (void) | ||||||
|  | { | ||||||
|  |   int elapsed = __spu_tb_timeout - spu_readch (SPU_RdDec); | ||||||
|  | #ifdef SPU_TIMER_DEBUG | ||||||
|  |   if (elapsed < 0) | ||||||
|  |     ABORT (); | ||||||
|  | #endif | ||||||
|  |   __spu_tb_val += elapsed; | ||||||
|  |  | ||||||
|  |   /* Adjust the timeout for the timer next to expire. Note this could cause | ||||||
|  |      the timeout to go negative, if it was just about to expire when we called | ||||||
|  |      spu_timer_start.  This is OK, since this can happen any time interrupts | ||||||
|  |      are disabled. We just schedule an immediate timeout in this case.  */ | ||||||
|  |   if (__spu_timers_active) | ||||||
|  |     { | ||||||
|  |       __spu_timers_active->tmout -= elapsed; | ||||||
|  |       if (__spu_timers_active->tmout < 0) | ||||||
|  | 	__spu_timers_active->tmout = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Add an allocated timer to the active list. The active list is sorted by | ||||||
|  |    timeout value. The timer at the head of the list is the timer that will | ||||||
|  |    expire next.  The rest of the timers have a timeout value that is relative | ||||||
|  |    to the timer ahead of it on the list.  This relative value is determined | ||||||
|  |    here, when the timer is added to the active list. When its position in the | ||||||
|  |    list is found, the timer's timeout value is set to its interval minus the | ||||||
|  |    sum of all the timeout values ahead of it.  The timeout value for the timer | ||||||
|  |    following the newly added timer is then adjusted to a new relative value. If | ||||||
|  |    the newly added timer is at the head of the list, the decrementer is reset. | ||||||
|  |    This function is called by SLIH to restart multiple timers (reset == 0) or | ||||||
|  |    by spu_timer_start() to start a single timer (reset == 1).  */ | ||||||
|  | void | ||||||
|  | __spu_timer_start (int id, int reset) | ||||||
|  | { | ||||||
|  |   spu_timer_t *t; | ||||||
|  |   spu_timer_t **pn; | ||||||
|  |   spu_timer_t *start = &__spu_timers[id]; | ||||||
|  |   unsigned tmout_time = 0; | ||||||
|  |   unsigned my_intvl = start->intvl; | ||||||
|  |   unsigned was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |  | ||||||
|  |   spu_idisable (); | ||||||
|  |  | ||||||
|  |   t = __spu_timers_active; | ||||||
|  |   pn = &__spu_timers_active; | ||||||
|  |  | ||||||
|  |   /* If the active list is empty, just add the timer with the timeout set to | ||||||
|  |      the interval. Otherwise find the place in the list for the timer, setting | ||||||
|  |      its timeout to its interval minus the sum of timeouts ahead of it.  */ | ||||||
|  |   start->state = SPU_TIMER_ACTIVE; | ||||||
|  |   if (__likely (!t)) | ||||||
|  |     { | ||||||
|  |       __spu_timers_active = start; | ||||||
|  |       start->next = NULL; | ||||||
|  |       start->tmout = my_intvl; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |       /* Update swtb and timeout val of the next timer, so all times are | ||||||
|  |          relative to now.  */ | ||||||
|  |       if (reset) | ||||||
|  | 	__update_spu_tb_val (); | ||||||
|  |  | ||||||
|  |       while (t && (my_intvl >= (tmout_time + t->tmout))) | ||||||
|  | 	{ | ||||||
|  | 	  tmout_time += t->tmout; | ||||||
|  | 	  pn = &t->next;; | ||||||
|  | 	  t = t->next; | ||||||
|  | 	} | ||||||
|  |       start->next = t; | ||||||
|  |       start->tmout = my_intvl - tmout_time; | ||||||
|  |       *pn = start; | ||||||
|  |  | ||||||
|  |       /* Adjust timeout for timer after us.  */ | ||||||
|  |       if (t) | ||||||
|  | 	t->tmout -= start->tmout; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (reset && (__spu_timers_active == start)) | ||||||
|  |     __reset_spu_decr (__spu_timers_active->tmout); | ||||||
|  |  | ||||||
|  |   if (__unlikely (was_enabled)) | ||||||
|  |     spu_ienable (); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* SLIH for decrementer.  Manages software timebase and timers. | ||||||
|  |    Called by SPU FLIH. Assumes decrementer is still running | ||||||
|  |    (event not yet acknowledeged).  */ | ||||||
|  | unsigned int | ||||||
|  | spu_clock_slih (unsigned status) | ||||||
|  | { | ||||||
|  |   int decr_reset_val; | ||||||
|  |   spu_timer_t *active, *handled; | ||||||
|  |   unsigned was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |  | ||||||
|  |   status &= ~MFC_DECREMENTER_EVENT; | ||||||
|  |  | ||||||
|  |   spu_idisable (); | ||||||
|  |  | ||||||
|  |   /* The decrementer has now expired.  The decrementer event was acknowledged | ||||||
|  |      in the FLIH but not disabled. The decrementer will continue to run while | ||||||
|  |      we're running the clock/timer handler. The software clock keeps running, | ||||||
|  |      and accounts for all the time spent running handlers. Add the current | ||||||
|  |      timeout to the software timebase and set the timeout to DECR_MAX. This | ||||||
|  |      allows the "clock read" code to continue to work while we're in here, and | ||||||
|  |      gives us the most possible time to finish before another underflow.  */ | ||||||
|  |   __spu_tb_val += __spu_tb_timeout; | ||||||
|  |   __spu_tb_timeout = DECR_MAX; | ||||||
|  |  | ||||||
|  |   /* For all timers that have the current timeout value, move them from the | ||||||
|  |      active list to the handled list and call their handlers. Note that the | ||||||
|  |      handled/stopped lists may be manipulated by the handlers if they wish to | ||||||
|  |      stop/free the timers. Note that only the first expired timer will reflect | ||||||
|  |      the real timeout value; the rest of the timers that had the same timeout | ||||||
|  |      value will have a relative value of zero.  */ | ||||||
|  |   if (__spu_timers_active) | ||||||
|  |     { | ||||||
|  |       __spu_timers_active->tmout = 0; | ||||||
|  |       while ((active = __spu_timers_active) | ||||||
|  | 	     && (active->tmout <= TIMER_INTERVAL_WINDOW)) | ||||||
|  | 	{ | ||||||
|  | 	  __spu_timers_active = active->next; | ||||||
|  | 	  active->next = __spu_timers_handled; | ||||||
|  | 	  __spu_timers_handled = active; | ||||||
|  | 	  active->state = SPU_TIMER_HANDLED; | ||||||
|  | 	  (*active->func) (active->id); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* put the handled timers back on the list and restart decrementer.  */ | ||||||
|  |   while ((handled = __spu_timers_handled) != NULL) | ||||||
|  |     { | ||||||
|  |       __spu_timers_handled = handled->next; | ||||||
|  |       __spu_timer_start (handled->id, 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   /* Reset the decrementer before returning. If we have any active timers, we | ||||||
|  |      set it to the timeout value for the timer at the head of the list, else | ||||||
|  |      the default clock value.  */ | ||||||
|  |   decr_reset_val = __spu_timers_active ? __spu_timers_active->tmout : CLOCK_START_VALUE; | ||||||
|  |  | ||||||
|  |   __reset_spu_decr (decr_reset_val); | ||||||
|  |  | ||||||
|  |   if (__likely (was_enabled)) | ||||||
|  |     spu_ienable (); | ||||||
|  |  | ||||||
|  |   return status; | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								newlib/libc/machine/spu/spu_timer_slih_reg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								newlib/libc/machine/spu/spu_timer_slih_reg.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Services for SLIH registration.  */ | ||||||
|  | #include <spu_intrinsics.h> | ||||||
|  | #include <spu_timer.h> | ||||||
|  |  | ||||||
|  | #define SPU_EVENT_ID(_mask) \ | ||||||
|  |     (spu_extract(spu_cntlz(spu_promote(_mask, 0)), 0)) | ||||||
|  | typedef unsigned (*spu_slih_t) (unsigned); | ||||||
|  |  | ||||||
|  | extern spu_slih_t __spu_slih_handlers[]; | ||||||
|  |  | ||||||
|  | /* This function is called whenever an event occurs for which no second level | ||||||
|  |    event handler was registered. The default event handler does nothing and | ||||||
|  |    zeros the most significant event bit indicating that the event was processed | ||||||
|  |    (when in reality, it was discarded).  */ | ||||||
|  | unsigned | ||||||
|  | __spu_default_slih (unsigned events) | ||||||
|  | { | ||||||
|  |   unsigned int mse; | ||||||
|  |  | ||||||
|  |   mse = 0x80000000 >> SPU_EVENT_ID (events); | ||||||
|  |   events &= ~mse; | ||||||
|  |  | ||||||
|  |   return (events); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Registers a SPU second level interrupt handler for the events specified by | ||||||
|  |    mask. The event mask consists of a set of bits corresponding to the event | ||||||
|  |    status bits (see channel 0 description). A mask containing multiple  1 bits | ||||||
|  |     will set the second level event handler for each of the events.  */ | ||||||
|  | void | ||||||
|  | spu_slih_register (unsigned mask, spu_slih_t func) | ||||||
|  | { | ||||||
|  |   unsigned int id; | ||||||
|  |  | ||||||
|  |   while (mask) | ||||||
|  |     { | ||||||
|  |       id = SPU_EVENT_ID (mask); | ||||||
|  |       __spu_slih_handlers[id] = (func) ? func : __spu_default_slih; | ||||||
|  |       mask &= ~(0x80000000 >> id); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										101
									
								
								newlib/libc/machine/spu/spu_timer_stop.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								newlib/libc/machine/spu/spu_timer_stop.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* SPU timer stop library service.  */ | ||||||
|  | #include <spu_timer.h> | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  |  | ||||||
|  | /* Stop a timer.  Moves it from either the active or handled list to the | ||||||
|  |    stopped list. Returns 0 on sucess, timer was successfully stopped. | ||||||
|  |    Returns <0 - Failure: | ||||||
|  |     * SPU_TIMER_ERR_NOT_ACTIVE - timer was not active | ||||||
|  |     * SPU_TIMER_ERR_INVALID_ID - invalid timer id | ||||||
|  |     * SPU_TIMER_ERR_NOCLOCK    -  spu clock is not running  */ | ||||||
|  | int | ||||||
|  | spu_timer_stop (int id) | ||||||
|  | { | ||||||
|  |   spu_timer_t *t, **pn; | ||||||
|  |   unsigned was_enabled; | ||||||
|  |  | ||||||
|  |   if (id < 0 || id >= SPU_TIMER_NTIMERS) | ||||||
|  |     return SPU_TIMER_ERR_INVALID_ID; | ||||||
|  |  | ||||||
|  |   if (__spu_clock_startcnt == 0) | ||||||
|  |     return SPU_TIMER_ERR_NOCLOCK; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /* Free or stopped states.  */ | ||||||
|  |   if (__spu_timers[id].state == SPU_TIMER_ACTIVE || | ||||||
|  |       __spu_timers[id].state == SPU_TIMER_HANDLED) | ||||||
|  |     { | ||||||
|  |       was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |       spu_idisable (); | ||||||
|  |  | ||||||
|  |       /* Timer is on either active list or handled list.  */ | ||||||
|  |       t = (__spu_timers[id].state == SPU_TIMER_ACTIVE) | ||||||
|  | 	? __spu_timers_active : __spu_timers_handled; | ||||||
|  |  | ||||||
|  |       pn = (__spu_timers[id].state == SPU_TIMER_ACTIVE) | ||||||
|  | 	? &__spu_timers_active : &__spu_timers_handled; | ||||||
|  |  | ||||||
|  |       while (t && t->id != id) | ||||||
|  | 	{ | ||||||
|  | 	  pn = &t->next; | ||||||
|  | 	  t = t->next; | ||||||
|  | 	} | ||||||
|  | #ifdef SPU_TIMER_DEBUG | ||||||
|  |       if (!t) | ||||||
|  | 	ABORT (); /* Internal error.  */ | ||||||
|  | #endif | ||||||
|  |       /* Fix timeout of next timer and decrementer if we were at the head of | ||||||
|  |          the active list.  */ | ||||||
|  |       if (t->next) | ||||||
|  | 	{ | ||||||
|  | 	  t->next->tmout += t->tmout; | ||||||
|  | 	  if (__spu_timers_active == t) | ||||||
|  | 	    __reset_spu_decr (t->next->tmout); | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	__reset_spu_decr (CLOCK_START_VALUE); | ||||||
|  |  | ||||||
|  |       *pn = t->next; /* Update this elements to pointer.  */ | ||||||
|  |       t->next = __spu_timers_stopped; | ||||||
|  |       __spu_timers_stopped = t; | ||||||
|  |  | ||||||
|  |       __spu_timers[id].state = SPU_TIMER_STOPPED; | ||||||
|  |  | ||||||
|  |       if (__likely (was_enabled)) | ||||||
|  | 	spu_ienable (); | ||||||
|  |  | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   return SPU_TIMER_ERR_NOT_ACTIVE; | ||||||
|  | } | ||||||
							
								
								
									
										115
									
								
								newlib/libc/machine/spu/spu_timer_svcs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								newlib/libc/machine/spu/spu_timer_svcs.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | |||||||
|  | /* | ||||||
|  | (C) Copyright IBM Corp. 2008 | ||||||
|  |  | ||||||
|  | All rights reserved. | ||||||
|  |  | ||||||
|  | Redistribution and use in source and binary forms, with or without | ||||||
|  | modification, are permitted provided that the following conditions are met: | ||||||
|  |  | ||||||
|  | * Redistributions of source code must retain the above copyright notice, | ||||||
|  | this list of conditions and the following disclaimer. | ||||||
|  | * 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. | ||||||
|  | * Neither the name of IBM 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* SPU timer start and alloc library services.  */ | ||||||
|  | #include <spu_timer.h> | ||||||
|  | #include "spu_timer_internal.h" | ||||||
|  |  | ||||||
|  | /* The timers.  */ | ||||||
|  | spu_timer_t __spu_timers[SPU_TIMER_NTIMERS] __attribute__ ((aligned (16))); | ||||||
|  |  | ||||||
|  | /* Active timer list.  */ | ||||||
|  | spu_timer_t *__spu_timers_active; | ||||||
|  |  | ||||||
|  | /* Stopped (allocated) timer list.  */ | ||||||
|  | spu_timer_t *__spu_timers_stopped; | ||||||
|  |  | ||||||
|  | /* List of timers being handled.  */ | ||||||
|  | spu_timer_t *__spu_timers_handled; | ||||||
|  |  | ||||||
|  | /* Bitmask of available timers.  */ | ||||||
|  | unsigned __spu_timers_avail = | ||||||
|  |   ((1 << (SPU_TIMER_NTIMERS - 1)) + ((1 << (SPU_TIMER_NTIMERS - 1)) - 1)); | ||||||
|  |  | ||||||
|  | /* Allocates an SPU interval timer and returns the timer ID. Must be called | ||||||
|  |    before starting a timer. interval specifies the expiration interval in | ||||||
|  |    timebase units. func specifies the function pointer to expiration handler. | ||||||
|  |    Returns the timer ID on success or <0 on Failure: | ||||||
|  |     * SPU_TIMER_ERR_NONE_FREE - no free timers to allocate | ||||||
|  |     * SPU_TIMER_ERR_INVALID_PARM - invalid parm  */ | ||||||
|  | int | ||||||
|  | spu_timer_alloc (int interval, void (*func) (int)) | ||||||
|  | { | ||||||
|  |   unsigned was_enabled; | ||||||
|  |   int id; | ||||||
|  |   if (interval < MIN_INTVL || interval > MAX_INTVL || func == NULL) | ||||||
|  |     return SPU_TIMER_ERR_INVALID_PARM; | ||||||
|  |  | ||||||
|  |   was_enabled = spu_readch (SPU_RdMachStat) & 0x1; | ||||||
|  |  | ||||||
|  |   /* Get id of next available timer.  */ | ||||||
|  |   id = spu_extract ((spu_sub ((unsigned) 31, | ||||||
|  | 				  spu_cntlz (spu_promote | ||||||
|  | 					     (__spu_timers_avail, 0)))), 0); | ||||||
|  |  | ||||||
|  |   /* No timers avail.  */ | ||||||
|  |   if (id == -1) | ||||||
|  |     return SPU_TIMER_ERR_NONE_FREE; | ||||||
|  |  | ||||||
|  |   /* Higher order bits represent lower timer ids.  */ | ||||||
|  |   __spu_timers_avail &= ~(1 << (id)); | ||||||
|  |   id = (SPU_TIMER_NTIMERS - 1) - id; | ||||||
|  |  | ||||||
|  |   /* Initialize timer and put it on stopped list.  */ | ||||||
|  |   (__spu_timers + id)->func = func; | ||||||
|  |   (__spu_timers + id)->intvl = interval; | ||||||
|  |   (__spu_timers + id)->id = id; | ||||||
|  |   (__spu_timers + id)->state = SPU_TIMER_STOPPED; | ||||||
|  |  | ||||||
|  |   spu_idisable (); | ||||||
|  |   (__spu_timers + id)->next = __spu_timers_stopped; | ||||||
|  |   __spu_timers_stopped = &__spu_timers[id]; | ||||||
|  |  | ||||||
|  |   if (__likely (was_enabled)) | ||||||
|  |     spu_ienable (); | ||||||
|  |   return id; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* External interface for starting a timer.  See description of | ||||||
|  |    __spu_timer_start(). Returns 0 on success and <0 on failure: | ||||||
|  |     * SPU_TIMER_ERR_INVALID_ID - invalid id | ||||||
|  |     * SPU_TIMER_ERR_NOCLOCK - clock is off | ||||||
|  |     * SPU_TIMER_ERR_NOT_STOPPED - timer not in stopped state  */ | ||||||
|  | int | ||||||
|  | spu_timer_start (int id) | ||||||
|  | { | ||||||
|  |   if (id < 0 || id >= SPU_TIMER_NTIMERS) | ||||||
|  |     return SPU_TIMER_ERR_INVALID_ID; | ||||||
|  |  | ||||||
|  |   if (__spu_clock_startcnt == 0) | ||||||
|  |     return SPU_TIMER_ERR_NOCLOCK; | ||||||
|  |  | ||||||
|  |   if (__spu_timers[id].state != SPU_TIMER_STOPPED) | ||||||
|  |     return SPU_TIMER_ERR_NOT_STOPPED; | ||||||
|  |  | ||||||
|  |   __spu_timer_start (id, 1); | ||||||
|  |  | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user