[1] Andes N1068体系移植

a. Libc改用官方版本(工具链附带版本);
    b. 去除未使用文件;
This commit is contained in:
ArcherChang 2017-08-25 14:25:35 +08:00
parent 921fbfbc21
commit 652ea85a39
44 changed files with 40 additions and 3477 deletions

View File

@ -1,2 +1,2 @@
text (code + rodata) data bss dec hex filename
54224 (45672 + 8552) 328 9820 64372 fb74 rtthread.elf
67240 (58320 + 8920) 408 10168 77816 12ff8 rtthread.elf

View File

@ -38,7 +38,7 @@ PLATFORM_PATH := $(BSP_PATH)/AE210P
ARCH_SEL_PATH := $(ARCH_PATH)/nds32
CONFIG_PATH := $(PLATFORM_PATH)
BOARD_PATH := $(PLATFORM_PATH)/board
LIBC_PATH := $(PLATFORM_PATH)/libc
#LIBC_PATH := $(PLATFORM_PATH)/libc
LDSCRIPT := $(BOARD_PATH)/ae210p.ld
CONFIG_H := $(CONFIG_PATH)/config.h
PLATFORM_DEF := -DAE210P
@ -63,8 +63,6 @@ INCLUDE_PATH := \
-I$(BOARD_PATH) \
-I$(DRIVERS_PATH) \
-I$(CLI_PATH) \
-I$(LIBC_PATH) \
-I${PLATFORM_PATH}/include \
-I$(COMPONENTS_DRVINC_PATH) \
-I$(COMPONENTS_DRVINC_DRV_PATH) \
-I$(COMPONENTS_INIT_PATH)
@ -86,7 +84,7 @@ CFLAGS := \
$(PLATFORM_DEF) \
$(OS_DEF) \
$(SMALL_HEAP_DEF) \
-fno-builtin -fomit-frame-pointer -funroll-loops -nostdlib \
-fno-builtin -fomit-frame-pointer -funroll-loops \
-fno-strict-aliasing -ffunction-sections \
$(CMODEL) \
$(OPTIM) \
@ -213,25 +211,25 @@ DRIVER_SRC := \
$(COMPONENTS_DRV_PATH)/serial/serial.c
# $(PLATFORM_PATH)/driver/dma/dmad.c
LIBC_SRC := \
$(LIBC_PATH)/stdio/fgets.c \
$(LIBC_PATH)/stdio/fputs.c \
$(LIBC_PATH)/stdio/fprintf.c \
$(LIBC_PATH)/stdio/do_printf.c \
$(LIBC_PATH)/stdio/printf.c \
$(LIBC_PATH)/string/memcpy.c \
$(LIBC_PATH)/string/memmove.c \
$(LIBC_PATH)/string/memset.c \
$(LIBC_PATH)/string/strcat.c \
$(LIBC_PATH)/string/strcasecmp.c \
$(LIBC_PATH)/string/strcmp.c \
$(LIBC_PATH)/string/strcpy.c \
$(LIBC_PATH)/string/strdup.c \
$(LIBC_PATH)/string/strlen.c \
$(LIBC_PATH)/string/strstr.c \
$(LIBC_PATH)/string/strupr.c \
$(LIBC_PATH)/string/wchar.c \
$(LIBC_PATH)/stdlib/qsort.c
#LIBC_SRC := \
# $(LIBC_PATH)/stdio/fgets.c \
# $(LIBC_PATH)/stdio/fputs.c \
# $(LIBC_PATH)/stdio/fprintf.c \
# $(LIBC_PATH)/stdio/do_printf.c \
# $(LIBC_PATH)/stdio/printf.c \
# $(LIBC_PATH)/string/memcpy.c \
# $(LIBC_PATH)/string/memmove.c \
# $(LIBC_PATH)/string/memset.c \
# $(LIBC_PATH)/string/strcat.c \
# $(LIBC_PATH)/string/strcasecmp.c \
# $(LIBC_PATH)/string/strcmp.c \
# $(LIBC_PATH)/string/strcpy.c \
# $(LIBC_PATH)/string/strdup.c \
# $(LIBC_PATH)/string/strlen.c \
# $(LIBC_PATH)/string/strstr.c \
# $(LIBC_PATH)/string/strupr.c \
# $(LIBC_PATH)/string/wchar.c \
# $(LIBC_PATH)/stdlib/qsort.c
#LIBC_FILE_SRC := \
# $(LIBC_PATH)/stdio/file.c \
@ -251,8 +249,8 @@ SRCS := \
${RTOS_SRC} \
${DRIVER_SRC} \
${CLI_SRC} \
${APP_SRCS} \
${LIBC_SRC}
${APP_SRCS} #\
# ${LIBC_SRC}
ALL_C_SRCS := ${SRCS}
ALL_AS_SRCS += ${BOOT_SRC}

View File

@ -90,21 +90,21 @@ void rt_init_thread_entry(void* parameter)
#endif /* #ifdef RT_USING_RTGUI */
}
#include "debug.h"
rt_thread_t test_thread[2];
void rt_test_thread_entry(void *parameter)
{
uint32_t num = (uint32_t)parameter;
uint32_t schedule_times = 0;
while (1)
{
DEBUG(1, 0, "%d:%d\r\n", num, schedule_times++);
rt_thread_delay(1);
}
}
//#include "debug.h"
//
//rt_thread_t test_thread[2];
//
//void rt_test_thread_entry(void *parameter)
//{
// uint32_t num = (uint32_t)parameter;
// uint32_t schedule_times = 0;
//
// while (1)
// {
// DEBUG(1, 0, "%d:%d\r\n", num, schedule_times++);
// rt_thread_delay(1);
// }
//}
int rt_application_init(void)
{

View File

@ -1,51 +0,0 @@
#ifndef __CTYPE_H__
#define __CTYPE_H__
static inline int islower(int c)
{
return c >= 'a' && c <= 'z';
}
static inline int isupper(int c)
{
return c >= 'A' && c <= 'Z';
}
static inline int isalpha(int c)
{
return islower(c) || isupper(c);
}
static inline int isdigit(int c)
{
return c >= '0' && c <= '9';
}
static inline int isalnum(int c)
{
return isalpha(c) || isdigit(c);
}
static inline int isblank(int c)
{
return c == ' ' || c == '\t';
}
static inline int isspace(int c)
{
return c == ' ';
}
static inline int isxdigit(int c)
{
return (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z');
}
// static inline int isascii(int c)
// static inline int iscntrl(int c)
// static inline int isgraph(int c)
// static inline int isprint(int c)
// static inline int ispunct(int c)
#endif /* __CTYPE_H__ */

View File

@ -1,20 +0,0 @@
#include "../library/ndsvfs/include/ndsvfs.h"
struct dirent {
int d_cnt;
int d_ino;
int d_off;
char d_name[256];
};
struct dir {
int d_cnt;
int d_off;
NDSVFS_FILE *d_file;
struct dirent *d_dirent;
NDSVFS_DENTRY *vde_list;
NDSVFS_DENTRY *vde_head;
};

View File

@ -1,18 +0,0 @@
#ifndef _STDINT_H
#include <stdint.h>
#if 0
#ifndef __INTTYPES_H__
#define __INTTYPES_H__
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif
#endif
#endif /* __INTTYPES_H__ */

View File

@ -1,324 +0,0 @@
#ifndef __LIST_H__
#define __LIST_H__
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void*) 0x00100100)
#define LIST_POISON2 ((void*) 0x00200200)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
#endif
#define container_of(ptr, type, member) ( { \
const typeof(((type*)0)->member ) *__mptr = (ptr); \
(type*)((char*)__mptr - offsetof(type,member) );})
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry) {
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is
* empty _and_ checks that no other CPU might be
* in the process of still modifying either member
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
static inline int list_swap(struct list_head *a, struct list_head *b, struct list_head *list)
{
if (a->next == list || b->prev == list)
return -1;
list_del(a);
list_add(a, b);
return 0;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use as a start point in
* list_for_each_entry_continue
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - iterate over list of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_reverse_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse_safe(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
#endif /* __LIST_H__ */

View File

@ -1,130 +0,0 @@
/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/*
* ISO C Standard: 7.15 Variable arguments <stdarg.h>
*/
#ifndef _STDARG_H
#ifndef _ANSI_STDARG_H_
#ifndef __need___va_list
#define _STDARG_H
#define _ANSI_STDARG_H_
#endif /* not __need___va_list */
#undef __need___va_list
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif
/* Define the standard macros for the user,
if this invocation was from the user program. */
#ifdef _STDARG_H
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#define va_copy(d,s) __builtin_va_copy(d,s)
#endif
#define __va_copy(d,s) __builtin_va_copy(d,s)
/* Define va_list, if desired, from __gnuc_va_list. */
/* We deliberately do not define va_list when called from
stdio.h, because ANSI C says that stdio.h is not supposed to define
va_list. stdio.h needs to have access to that data type,
but must not use that name. It should use the name __gnuc_va_list,
which is safe because it is reserved for the implementation. */
#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */
#undef _VA_LIST
#endif
#ifdef _BSD_VA_LIST
#undef _BSD_VA_LIST
#endif
#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST))
/* SVR4.2 uses _VA_LIST for an internal alias for va_list,
so we must avoid testing it and setting it here.
SVR4 uses _VA_LIST as a flag in stdarg.h, but we should
have no conflict with that. */
#ifndef _VA_LIST_
#define _VA_LIST_
#ifdef __i860__
#ifndef _VA_LIST
#define _VA_LIST va_list
#endif
#endif /* __i860__ */
typedef __gnuc_va_list va_list;
#ifdef _SCO_DS
#define __VA_LIST
#endif
#endif /* _VA_LIST_ */
#else /* not __svr4__ || _SCO_DS */
/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.
But on BSD NET2 we must not test or define or undef it.
(Note that the comments in NET 2's ansi.h
are incorrect for _VA_LIST_--see stdio.h!) */
#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT)
/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */
#ifndef _VA_LIST_DEFINED
/* The macro _VA_LIST is used in SCO Unix 3.2. */
#ifndef _VA_LIST
/* The macro _VA_LIST_T_H is used in the Bull dpx2 */
#ifndef _VA_LIST_T_H
/* The macro __va_list__ is used by BeOS. */
#ifndef __va_list__
typedef __gnuc_va_list va_list;
#endif /* not __va_list__ */
#endif /* not _VA_LIST_T_H */
#endif /* not _VA_LIST */
#endif /* not _VA_LIST_DEFINED */
#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__))
#define _VA_LIST_
#endif
#ifndef _VA_LIST
#define _VA_LIST
#endif
#ifndef _VA_LIST_DEFINED
#define _VA_LIST_DEFINED
#endif
#ifndef _VA_LIST_T_H
#define _VA_LIST_T_H
#endif
#ifndef __va_list__
#define __va_list__
#endif
#endif /* not _VA_LIST_, except on certain systems */
#endif /* not __svr4__ */
#endif /* _STDARG_H */
#endif /* not _ANSI_STDARG_H_ */
#endif /* not _STDARG_H */

View File

@ -1,5 +0,0 @@
#ifndef __STDDEF_H__
#define __STDDEF_H__
typedef unsigned long size_t;
#endif /* __STDDEF_H__ */

View File

@ -1,64 +0,0 @@
#ifndef __STDIO_H__
#define __STDIO_H__
#include <stdarg.h> /* va_list, va_arg() */
#include <stddef.h> /* size_t */
#include <stdlib.h>
//#include <dirent.h>
// FIXME: find a right place to define the following things
// constants
typedef int fpos_t;
#define FSEEK_SET 0 // origin is beginning of the file
#define FSEEK_CUR 1 // origin is current position
#define FSEEK_END 2 // origin is end of the file
typedef unsigned long FILE;
typedef int time_t;
struct stat {
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
int st_size; /* total size, in bytes */
int st_blksize; /* blocksize for file system I/O */
int st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
#define stdin ((void*)0)
#define stdout ((void*)0)
#define stderr ((void*)0)
#define EOF (-1)
int vsprintf(char *buffer, const char *fmt, va_list args);
int sprintf(char *buffer, const char *fmt, ...);
int vprintf(const char *fmt, va_list args);
int printf(const char *fmt, ...);
int fprintf(FILE *stream, const char *format, ...);
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *fp);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
struct dir *opendir(const char *path);
struct dirent *readdir(struct dir *dirp);
int closedir(struct dir *dirp);
int fstat(FILE* fd, struct stat *buf);
#endif /* __STDIO_H__ */

View File

@ -1,70 +0,0 @@
#ifndef __STDLIB_H__
#define __STDLIB_H__
#include <stddef.h>
#include <string.h>
#ifndef NULL
#define NULL ((void*)0)
#endif
#if defined(CONFIG_OS_UCOS_II) || defined(CONFIG_OS_UCOS_III)
#include "kmem.h"
static inline void *malloc(size_t size)
{
return kmalloc(size);
}
static inline void free(void *ptr)
{
return kfree(ptr);
}
#elif defined(CONFIG_OS_FREERTOS)
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define malloc pvPortMalloc
#define free vPortFree
#elif defined(CONFIG_OS_THREADX)
#include "kmem.h"
static inline void *malloc(size_t size)
{
return kmalloc(size);
}
static inline void free(void *ptr)
{
return kfree(ptr);
}
#elif defined(CONFIG_OS_RTTHREAD)
#include "rtdef.h"
#include "rtthread.h"
#define malloc rt_malloc
#define free rt_Free
#else
# error "No valid OS is defined!"
#endif
static inline void *calloc(size_t nmemb, size_t size)
{
int i = nmemb * size;
unsigned char *ret = malloc(i);
while (i >= 0)
ret[--i] = '\0';
return ret;
}
static inline void *realloc(void *ptr, size_t size)
{
return NULL;
}
static inline void exit(int status)
{
}
static inline void abort(void)
{
}
void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
extern int atoi(const char *__nptr);
#endif /* __STDLIB_H__ */

View File

@ -1,51 +0,0 @@
#ifndef __STRING_H__
#define __STRING_H__
#include <stddef.h>
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
extern void *memset(void *s, int c, size_t n);
extern void bzero(void *, size_t);
extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t n);
extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t n);
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern char *strcpy(char *dest, const void *src);
extern char *strncpy(char *dest, const void *src, size_t n);
extern char *strdup(const char *s);
extern char *strndup(const char *s, size_t n);
extern size_t strlen(const char *s);
extern size_t strnlen(const char *s, size_t maxlen);
extern char *strstr(const char *haystack, const char *needle);
extern unsigned long int strtoul(const char *nptr, char **endptr, int base);
extern char *strupr(char *str);
/* wchar_t */
#ifndef WCHAR
typedef unsigned short WCHAR;
#endif // WCHAR
#ifndef wchar_t
typedef unsigned short wchar_t;
#endif // wchar
extern wchar_t *wcscat(wchar_t *str_dst, const wchar_t *str_src);
extern int wcscmp(const wchar_t *string1, const wchar_t *string2);
extern int wcsncmp(const wchar_t *string1, const wchar_t *string2, int count);
extern wchar_t *wcscpy(wchar_t *str_dst, const wchar_t *str_src);
extern wchar_t *wcsncpy(wchar_t *str_dst, const wchar_t *str_src, int count);
extern int wcslen(const wchar_t *str);
extern wchar_t *wcsupr(wchar_t *str);
extern wchar_t *wcslwr(wchar_t *str);
#endif /* __STRING_H__ */

View File

@ -1,220 +0,0 @@
#include "kmem.h"
#include "slab.h"
#include "debug.h"
#include "hal.h"
static struct page_struct mem_map[MEM_LIMIT >> PG_SHIFT];
static intptr_t kmem_start;
static intptr_t kmem_end;
static intptr_t kmem_size;
static intptr_t kmem_total_pages;
static intptr_t kmem_free_pages;
static inline int pg_is_free(struct page_struct *page)
{
return page->flag & PG_FLAG_FREE;
}
static inline void *pf_to_addr(intptr_t pg_idx)
{
return (void*)(kmem_start + (pg_idx << PG_SHIFT));
}
static inline intptr_t addr_to_pf(void *addr)
{
return (intptr_t)(addr - kmem_start) >> PG_SHIFT;
}
static inline void pg_flag_set(intptr_t start, intptr_t count, uint32_t flag)
{
while (count-- > 0)
mem_map[start + count].flag |= flag;
}
static inline void pg_flag_clr(intptr_t start, intptr_t count, uint32_t flag)
{
while (count-- > 0)
mem_map[start + count].flag &= ~flag;
}
struct page_struct *addr_to_pf_des(void *addr)
{
return &mem_map[addr_to_pf(addr)];
}
int init_kmem(intptr_t start, intptr_t end)
{
extern char *_end;
if((unsigned int)start < (unsigned int)&_end)
KPANIC("start and _end are overlap. start:%08x, _end=%08x\n", start, &_end);
kmem_start = start & PG_MASK;
kmem_end = end & PG_MASK;
kmem_size = kmem_end - kmem_start;
kmem_total_pages = kmem_size >> PG_SHIFT;
kmem_free_pages = kmem_total_pages;
pg_flag_set(0, kmem_total_pages, PG_FLAG_FREE);
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing MM *\n");
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 1, "Start:0x%08x End:0x%08x, Size:0x%08x(%dK), Pages:%d\n",
kmem_start, kmem_end, kmem_size,
kmem_size >> 10, kmem_total_pages);
#ifdef CONFIG_KMEM_SLAB
init_cache();
#endif
return 0;
}
void *alloc_pages(intptr_t pg_req_nr)
{
intptr_t pg_begin_idx = -1;
intptr_t pg_found_nr = 0;
intptr_t i = 0;
DEBUG(0, 1, "Requesting for %d/%d/%d pages\n",
pg_req_nr, kmem_free_pages, kmem_total_pages);
if (kmem_free_pages < pg_req_nr)
return (void*)0;
for (i = 0; i < kmem_total_pages; i++) {
if (!pg_is_free(&mem_map[i])) {
pg_begin_idx = -1;
continue;
}
if (pg_begin_idx < 0) {
pg_begin_idx = i;
pg_found_nr = 1;
}
else {
pg_found_nr++;
}
if (pg_found_nr == pg_req_nr) {
pg_flag_clr(pg_begin_idx, pg_req_nr, PG_FLAG_FREE);
mem_map[pg_begin_idx].alloc_nr = pg_req_nr;
kmem_free_pages -= pg_req_nr;
DEBUG(0, 1, "return mem_map %d pages at [%d]:0x%08x\n",
pg_req_nr, pg_begin_idx, (intptr_t)pf_to_addr(pg_begin_idx));
return pf_to_addr(pg_begin_idx);
}
}
return (void*)0;
}
void *alloc_page(void)
{
return alloc_pages(1);
}
void free_pages(void *addr)
{
intptr_t idx = addr_to_pf(addr);
KASSERT(!pg_is_free(&mem_map[idx]))
pg_flag_set(idx, mem_map[idx].alloc_nr, PG_FLAG_FREE);
DEBUG(0, 1, "0x:%08x, idx:%d, pages:%d, phy_addr:%08x\n",
(intptr_t)addr, idx, mem_map[idx].alloc_nr,
(intptr_t)pf_to_addr(idx));
kmem_free_pages += mem_map[idx].alloc_nr;
mem_map[idx].alloc_nr = 0;
}
void *kmalloc(intptr_t size)
{
void *addr = 0;
intptr_t pg_req_nr = 0;
int core_intl = 0;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
DEBUG(0, 1, "%d bytes at:", size);
#ifdef CONFIG_KMEM_USING_SLAB
addr = kmem_cache_alloc_gen(size);
if (addr) {
DEBUG(0, 0, " 0x%08x\n", (intptr_t)addr);
hal_global_int_ctl(core_intl);
return addr;
}
#endif
size = (size + (PG_SIZE - 1)) & PG_MASK;
pg_req_nr = size >> PG_SHIFT;
if (pg_req_nr <= kmem_free_pages) {
addr = alloc_pages(pg_req_nr);
DEBUG(0, 0, " 0x%08x\n", (intptr_t)addr);
}
else {
DEBUG(0, 0, "FAIL:(req:%d, free:%d)\n", pg_req_nr, kmem_free_pages);
}
hal_global_int_ctl(core_intl);
return addr;
}
void kfree(void *addr)
{
int core_intl = 0;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
#ifdef CONFIG_KMEM_USING_SLAB
struct page_struct *pg = addr_to_pf_des(addr);
struct cache_struct *cp = GET_PAGE_CACHE(pg);
if (cp) {
DEBUG(0, 1, "0x%08x\n", (intptr_t)addr);
kmem_cache_free(cp, addr);
hal_global_int_ctl(core_intl);
return;
}
#endif
DEBUG(0, 1, "0x%08x\n", (intptr_t)addr);
free_pages(addr);
hal_global_int_ctl(core_intl);
}
void mem_dump_map(void)
{
intptr_t i;
DEBUG(1, 1, "*:free +: begin of allocated chunk, -:allocated\n");
for (i = 0; i < kmem_total_pages; i++) {
if (i%32 == 0)
DEBUG(1, 0, "\n0x%08x\t: ", kmem_start + i * PG_SIZE);
else if (i%8 == 0)
DEBUG(1, 0, " ");
if (pg_is_free(&mem_map[i]))
DEBUG(1, 0, "*");
else if (mem_map[i].alloc_nr)
DEBUG(1, 0, "+");
else
DEBUG(1, 0, "-");
}
DEBUG(1, 0, "\n");
}

View File

@ -1,74 +0,0 @@
#ifndef __KMEM_H__
#define __KMEM_H__
#include <inttypes.h>
#include "list.h"
#define PG_FLAG_FREE 0x00000001
#ifdef CONFIG_PLAT_AE210P
#include "ae210p_regs.h"
#define PG_MASK 0xFFFFFF00
#define PG_SHIFT 8
#define PG_SIZE (1 << PG_SHIFT) //256Byte per page
/* 48MB ~ 112MB */
#define MEM_START 0x00208000 //EDLM_BASEi+32K
#define MEM_END 0x00210000 //EDLM_BASE+64K
#elif defined( CONFIG_LATENCY_HEAP )
#define PG_MASK 0xFFFFFFC0
#define PG_SHIFT 6
#define PG_SIZE (1 << PG_SHIFT)
#define MEM_START 0x0C000
#define MEM_END 0x10000
#else
#ifdef CONFIG_PLAT_AG101P_16MB
#define PG_MASK 0xFFFFFF00
#define PG_SHIFT 8
#define PG_SIZE (1 << PG_SHIFT)
#ifdef CONFIG_SMALL_HEAP
/* 6MB ~ 7MB*/
#define MEM_START 0x00600000
#else
/* 3MB ~ 7MB*/
#define MEM_START 0x00300000
#endif
#define MEM_END 0x00700000
#else
#define PG_MASK 0xFFFFF000
#define PG_SHIFT 12
#define PG_SIZE (1 << PG_SHIFT)
/* 48MB ~ 112MB */
#define MEM_START 0x03000000
#define MEM_END 0x07000000
#endif
#endif
#define MEM_LIMIT ((MEM_END) - (MEM_START))
struct page_struct {
struct list_head lru;
uint32_t flag;
intptr_t alloc_nr;
};
extern int init_kmem(intptr_t start, intptr_t end);
extern void *alloc_pages(intptr_t pg_req_nr);
extern void *alloc_page(void);
extern void free_pages(void *addr);
extern void *kmalloc(intptr_t size);
extern void kfree(void *addr);
extern struct page_struct *addr_to_pf_des(void *addr);
extern void mem_dump_map(void);
#endif /* __KMEM_H__ */

View File

@ -1,324 +0,0 @@
#ifndef __LIST_H__
#define __LIST_H__
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void*) 0x00100100)
#define LIST_POISON2 ((void*) 0x00200200)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
#endif
#define container_of(ptr, type, member) ( { \
const typeof(((type*)0)->member ) *__mptr = (ptr); \
(type*)((char*)__mptr - offsetof(type,member) );})
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry) {
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is
* empty _and_ checks that no other CPU might be
* in the process of still modifying either member
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
static inline int list_swap(struct list_head *a, struct list_head *b, struct list_head *list)
{
if (a->next == list || b->prev == list)
return -1;
list_del(a);
list_add(a, b);
return 0;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use as a start point in
* list_for_each_entry_continue
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - iterate over list of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_reverse_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse_safe(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
#endif /* __LIST_H__ */

View File

@ -1,318 +0,0 @@
#include "list.h"
#include "slab.h"
#include "kmem.h"
#include "debug.h"
#include <string.h>
LIST_HEAD(cache_list);
struct cache_struct *cachep;
struct cache_struct *slabp;
struct cache_struct *kmem_cache_create(const char *name, intptr_t obj_size, handler_t ctor, handler_t dtor)
{
struct cache_struct *cp;
cp = kmem_cache_alloc(cachep);
KASSERT(cp);
strncpy(cp->name, name, CACHE_NAME_BUF_SIZE-1);
cp->obj_size = obj_size;
cp->page_nr = obj_size * 8 / PG_SIZE + 1;
cp->ctor = ctor;
cp->dtor = dtor;
cp->free_objs = 0;
if (cp->obj_size < (PG_SIZE >> 3))
cp->num = (PG_SIZE - sizeof(struct slab_struct)) / (sizeof(bufctl_t) + cp->obj_size);
else
cp->num = PG_SIZE / cp->obj_size;
cp->total_objs = 0;
INIT_LIST_HEAD(&cp->slab_full);
INIT_LIST_HEAD(&cp->slab_partial);
INIT_LIST_HEAD(&cp->slab_free);
INIT_LIST_HEAD(&cp->next);
list_add_tail(&cp->next, &cache_list);
DEBUG(0, 1, "Cache \"%s\" (size:%d) created\n", name, obj_size);
return cp;
}
static inline bufctl_t *slab_bufctl(struct slab_struct *sp)
{
return (bufctl_t*)(sp+1);
}
static void cache_init_objs(struct cache_struct *cp, struct slab_struct *sp, unsigned long ctor_flags)
{
intptr_t i;
DEBUG(0, 1, " %s:cp->num =%d\n", cp->name, cp->num);
for (i = 0; i < cp->num; i++) {
void *objp = (void*)(sp->s_mem + cp->obj_size*i);
if (cp->ctor)
cp->ctor(objp, cp, ctor_flags);
slab_bufctl(sp)[i] = (bufctl_t)(i+1);
}
slab_bufctl(sp)[i-1] = (bufctl_t)BUFCTL_END;
sp->next_free = 0;
}
static void kmem_cache_grow(struct cache_struct *cp)
{
void *addr;
struct slab_struct *sp;
struct page_struct *pg_des;
int i;
addr = alloc_pages(cp->page_nr);
KASSERT(addr);
if (cp->obj_size < (PG_SIZE >> 3)) {
sp = (struct slab_struct*)addr;
sp->s_mem = (void*)sp + sizeof(struct slab_struct) + sizeof(bufctl_t)*cp->num;
}
else {
sp = (struct slab_struct*)kmem_cache_alloc(slabp);
KASSERT(sp);
sp->s_mem = addr;
}
pg_des = addr_to_pf_des(addr);
i = cp->page_nr;
while (i--) {
SET_PAGE_CACHE(pg_des, cp);
SET_PAGE_SLAB(pg_des, sp);
pg_des++;
}
sp->cache = cp;
sp->ref_cnt = 0;
cache_init_objs(cp, sp, 0);
cp->free_objs += cp->num;
cp->total_objs += cp->num;
INIT_LIST_HEAD(&sp->list);
list_add_tail(&sp->list, &cp->slab_free);
DEBUG(0, 1, " %s:grow up, get %d more free object\n", cp->name, cp->free_objs);
}
static void *kmem_slab_refill(struct slab_struct *sp)
{
void *buf_addr;
intptr_t idx;
idx = sp->next_free;
sp->next_free = (intptr_t)(slab_bufctl(sp)[idx]);
slab_bufctl(sp)[idx] = BUFCTL_END;
DEBUG(0, 1, " %s:allocating %uth obj in a slab of Cache \n", sp->cache->name, idx);
if (sp->next_free == (intptr_t)BUFCTL_END) {
DEBUG(0, 1, " %s:move from slab_partial to slab_full\n", sp->cache->name);
list_move(&sp->list, &sp->cache->slab_full);
}
else if (sp->ref_cnt == 0) {
DEBUG(0, 1, " %s:move from slab_free to slab_partial\n", sp->cache->name);
list_move(&sp->list, &sp->cache->slab_partial);
}
sp->ref_cnt++;
sp->cache->free_objs--;
buf_addr = sp->s_mem + idx*sp->cache->obj_size;
return buf_addr;
}
static void slab_print_list(struct cache_struct *cp)
{
DEBUG(0, 1, " %s:partial[%c], free[%c], full[%c] %3d/%3d (%3d)\n",
cp->name,
list_empty(&cp->slab_partial)?' ':'*',
list_empty(&cp->slab_free)?' ':'*',
list_empty(&cp->slab_full)?' ':'*',
cp->free_objs,
cp->total_objs,
cp->num);
}
void *kmem_cache_alloc(struct cache_struct *cp)
{
struct slab_struct *sp;
slab_print_list(cp);
DEBUG(0, 1, " %s:free_objs = %d/%d\n", cp->name, cp->free_objs, cp->num);
while (!cp->free_objs)
kmem_cache_grow(cp);
list_for_each_entry(sp, &cp->slab_partial, list) {
DEBUG(0, 1, " %s:get a free obj from slab_partial list\n", cp->name);
return kmem_slab_refill(sp);
}
list_for_each_entry(sp, &cp->slab_free, list) {
DEBUG(0, 1, " %s:get a free obj from slab_free list\n", cp->name);
return kmem_slab_refill(sp);
}
KPANIC("%s:failed to alloc a free slab\n", cp->name);
}
void kmem_cache_free(struct cache_struct *cp, void *buf_addr)
{
struct page_struct *pg;
struct slab_struct *sp;
intptr_t idx;
pg = addr_to_pf_des(buf_addr);
sp = GET_PAGE_SLAB(pg);
idx = ((intptr_t)(buf_addr - sp->s_mem)) / cp->obj_size;
slab_bufctl(sp)[idx] = (bufctl_t)sp->next_free;
sp->next_free = idx;
DEBUG(0, 1, " %s:freeing %uth obj in a slab\n", cp->name, idx);
if (sp->ref_cnt == cp->num) {
DEBUG(0, 1, " %s:move from slab_full to slab_partial\n", cp->name);
list_move(&sp->list, &sp->cache->slab_partial);
}
else if (sp->ref_cnt == 1) {
DEBUG(0, 1, " %s:move from slab_partial to slab_free\n", cp->name);
list_move(&sp->list, &sp->cache->slab_free);
}
cp->free_objs++;
sp->ref_cnt--;
}
void kmem_cache_destory(struct cache_struct *cp)
{
if (!cp)
return;
}
void kmem_cache_reap(struct cache_struct *cp)
{
struct slab_struct *sp, *tmp;
slab_print_list(cp);
list_for_each_entry_safe(sp, tmp, &cp->slab_free, list) {
list_del(&sp->list);
if (cp->obj_size < (PG_SIZE >> 3))
free_pages(sp);
else
free_pages(sp->s_mem);
cp->free_objs -= cp->num;
DEBUG(0, 1, " %s:cache shrink, free_objs = %d\n", cp->name, cp->free_objs);
}
}
void init_cache(void)
{
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing SLAB *\n");
DEBUG(1, 0, "*************************************************\n");
/* Initialize the cachep statically */
cachep = (struct cache_struct*)alloc_page();
KASSERT(cachep);
strncpy(cachep->name, "cachep", CACHE_NAME_BUF_SIZE-1);
cachep->obj_size = sizeof(struct cache_struct);
cachep->page_nr = sizeof(struct cache_struct) * 8 / PG_SIZE + 1;
cachep->ctor = (void*)0;
cachep->dtor = (void*)0;
cachep->num = (PG_SIZE - sizeof(struct slab_struct)) / (sizeof(bufctl_t) + cachep->obj_size);
cachep->free_objs = 0;
cachep->total_objs = 0;
INIT_LIST_HEAD(&cachep->slab_full);
INIT_LIST_HEAD(&cachep->slab_partial);
INIT_LIST_HEAD(&cachep->slab_free);
INIT_LIST_HEAD(&cachep->next);
list_add_tail(&cachep->next, &cache_list);
slabp = kmem_cache_create("slabp", sizeof(struct cache_struct), (void*)0, (void*)0);
#ifdef CONFIG_KMEM_USING_SLAB
init_general_caches();
#endif
}
#define TBL_SIZE 10
#define MIN_OBJ_SIZE 8
struct cache_tbl_entry {
struct cache_struct *cp;
intptr_t size;
};
struct cache_tbl_entry cache_tbl[TBL_SIZE];
void init_general_caches(void)
{
char name_buf[CACHE_NAME_BUF_SIZE];
intptr_t size;
intptr_t i;
size = MIN_OBJ_SIZE;
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing SLAB(General Object Caches) *\n");
DEBUG(1, 0, "*************************************************\n");
for (i = 0; i < TBL_SIZE; i++) {
sprintf(name_buf, "gen_cache_%d", size);
cache_tbl[i].cp = kmem_cache_create(name_buf, size, (void*)0, (void*)0);
cache_tbl[i].size = size;
size *= 2;
}
}
void *kmem_cache_alloc_gen(intptr_t size)
{
int i;
for (i = 0; i < TBL_SIZE; i++) {
if (cache_tbl[i].size > size)
return kmem_cache_alloc(cache_tbl[i].cp);
}
return (void*)0;
}

View File

@ -1,59 +0,0 @@
#ifndef __SLAB_H__
#define __SLAB_H__
#include <inttypes.h>
#include "list.h"
#define BUFCTL_END (((bufctl_t)(~0U))-0)
#define BUFCTL_FREE (((bufctl_t)(~0U))-1)
#define SLAB_LIMIT (((bufctl_t)(~0U))-2)
#define CACHE_NAME_BUF_SIZE 20
struct cache_struct;
typedef void (*handler_t)(void *, struct cache_struct*, intptr_t);
struct cache_struct {
struct list_head slab_full;
struct list_head slab_partial;
struct list_head slab_free;
struct list_head next;
char name[CACHE_NAME_BUF_SIZE];
intptr_t obj_size;
intptr_t page_nr;
intptr_t num;
intptr_t free_objs;
intptr_t total_objs;
handler_t ctor;
handler_t dtor;
};
struct slab_struct {
struct cache_struct *cache;
struct list_head list;
void *s_mem;
int ref_cnt;
intptr_t next_free;
};
typedef intptr_t *bufctl_t;
extern struct cache_struct *kmem_cache_create(const char *name, intptr_t obj_size, handler_t ctor, handler_t dtor);
extern void *kmem_cache_alloc(struct cache_struct *cp);
extern void kmem_cache_free(struct cache_struct *cp, void *buf_addr);
extern void *kmem_cache_alloc_gen(intptr_t size);
extern void kmem_cache_destory(struct cache_struct *cp);
extern void kmem_cache_reap(struct cache_struct *cp);
extern void init_cache(void);
extern void init_general_caches(void);
#define SET_PAGE_CACHE(pg,x) ((pg)->lru.next = (struct list_head*)(x))
#define GET_PAGE_CACHE(pg) ((struct cache_struct*)(pg)->lru.next)
#define SET_PAGE_SLAB(pg,x) ((pg)->lru.prev = (struct list_head*)(x))
#define GET_PAGE_SLAB(pg) ((struct slab_struct*)(pg)->lru.prev)
#endif /* __SLAB_H__ */

View File

@ -1,6 +0,0 @@
lib-y += do_printf.o
lib-y += fgets.o
lib-y += file.o
lib-y += fprintf.o
lib-y += fputs.o
lib-y += printf.o

View File

@ -1,280 +0,0 @@
#include <string.h> /* strlen() */
#include "do_printf.h"
/*****************************************************************************
Revised Jan 28, 2002
- changes to make characters 0x80-0xFF display properly
Revised June 10, 2001
- changes to make vsprintf() terminate string with '\0'
Revised May 12, 2000
- math in DO_NUM is now unsigned, as it should be
- %0 flag (pad left with zeroes) now works
- actually did some TESTING, maybe fixed some other bugs
name: do_printf
action: minimal subfunction for ?printf, calls function
'fn' with arg 'ptr' for each character to be output
returns:total number of characters output
%[flag][width][.prec][mod][conv]
flag: - left justify, pad right w/ blanks DONE
0 pad left w/ 0 for numerics DONE
+ always print sign, + or - no
' ' (blank) no
# (???) no
width: (field width) DONE
prec: (precision) no
conv: d,i decimal int DONE
u decimal unsigned DONE
o octal DONE
x,X hex DONE
f,e,g,E,G float no
c char DONE
s string DONE
p ptr DONE
mod: N near ptr DONE
F far ptr no
h short (16-bit) int DONE
l long (32-bit) int DONE
L long long (64-bit) int no
*****************************************************************************/
/* flags used in processing format string */
#define PR_LJ 0x01 /* left justify */
#define PR_CA 0x02 /* use A-F instead of a-f for hex */
#define PR_SG 0x04 /* signed numeric conversion (%d vs. %u) */
#define PR_32 0x08 /* long (32-bit) numeric conversion */
#define PR_16 0x10 /* short (16-bit) numeric conversion */
#define PR_WS 0x20 /* PR_SG set and num was < 0 */
#define PR_LZ 0x40 /* pad left with '0' instead of ' ' */
#define PR_FP 0x80 /* pointers are far */
/* largest number handled is 2^32-1, lowest radix handled is 8.
2^32-1 in base 8 has 11 digits (add 5 for trailing NUL and for slop) */
#define PR_BUFLEN 16
int do_printf(const char *fmt, va_list args, fnptr_t fn, void *ptr)
{
unsigned state, flags, radix, actual_wd, count, given_wd;
unsigned char *where, buf[PR_BUFLEN];
long num;
state = flags = count = given_wd = 0;
/* begin scanning format specifier list */
for(; *fmt; fmt++)
{
switch(state)
{
/* STATE 0: AWAITING % */
case 0:
if(*fmt != '%') /* not %... */
{
fn(*fmt, &ptr); /* ...just echo it */
count++;
break;
}
/* found %, get next char and advance state to check if next char is a flag */
state++;
fmt++;
/* FALL THROUGH */
/* STATE 1: AWAITING FLAGS (%-0) */
case 1:
if(*fmt == '%') /* %% */
{
fn(*fmt, &ptr);
count++;
state = flags = given_wd = 0;
break;
}
if(*fmt == '-')
{
if(flags & PR_LJ)/* %-- is illegal */
state = flags = given_wd = 0;
else
flags |= PR_LJ;
break;
}
/* not a flag char: advance state to check if it's field width */
state++;
/* check now for '%0...' */
if(*fmt == '0')
{
flags |= PR_LZ;
fmt++;
}
/* FALL THROUGH */
/* STATE 2: AWAITING (NUMERIC) FIELD WIDTH */
case 2:
if(*fmt >= '0' && *fmt <= '9')
{
given_wd = 10 * given_wd +
(*fmt - '0');
break;
}
/* not field width: advance state to check if it's a modifier */
state++;
/* FALL THROUGH */
/* STATE 3: AWAITING MODIFIER CHARS (FNlh) */
case 3:
if(*fmt == 'F')
{
flags |= PR_FP;
break;
}
if(*fmt == 'N')
break;
if(*fmt == 'l')
{
flags |= PR_32;
break;
}
if(*fmt == 'h')
{
flags |= PR_16;
break;
}
/* not modifier: advance state to check if it's a conversion char */
state++;
/* FALL THROUGH */
/* STATE 4: AWAITING CONVERSION CHARS (Xxpndiuocs) */
case 4:
where = buf + PR_BUFLEN - 1;
*where = '\0';
switch(*fmt)
{
case 'X':
flags |= PR_CA;
/* FALL THROUGH */
/* xxx - far pointers (%Fp, %Fn) not yet supported */
case 'x':
case 'p':
case 'n':
radix = 16;
goto DO_NUM;
case 'd':
case 'i':
flags |= PR_SG;
/* FALL THROUGH */
case 'u':
radix = 10;
goto DO_NUM;
case 'o':
radix = 8;
/* load the value to be printed. l=long=32 bits: */
DO_NUM: if(flags & PR_32)
num = va_arg(args, unsigned long);
/* h=short=16 bits (signed or unsigned) */
else if(flags & PR_16)
{
if(flags & PR_SG)
num = va_arg(args, unsigned long);
else
num = va_arg(args, unsigned long);
}
/* no h nor l: sizeof(int) bits (signed or unsigned) */
else
{
if(flags & PR_SG)
num = va_arg(args, unsigned long);
else
num = va_arg(args, unsigned long);
}
/* take care of sign */
if(flags & PR_SG)
{
if(num < 0)
{
flags |= PR_WS;
num = -num;
}
}
/* convert binary to octal/decimal/hex ASCII
OK, I found my mistake. The math here is _always_ unsigned */
do
{
unsigned long temp;
temp = (unsigned long)num % radix;
where--;
if(temp < 10)
*where = temp + '0';
else if(flags & PR_CA)
*where = temp - 10 + 'A';
else
*where = temp - 10 + 'a';
num = (unsigned long)num / radix;
}
while(num != 0);
goto EMIT;
case 'c':
/* disallow pad-left-with-zeroes for %c */
flags &= ~PR_LZ;
where--;
*where = (unsigned char)va_arg(args,
unsigned int);
actual_wd = 1;
goto EMIT2;
case 's':
/* disallow pad-left-with-zeroes for %s */
flags &= ~PR_LZ;
where = (unsigned char *)va_arg(args, unsigned int);
EMIT:
actual_wd = strlen((const char *)where);
if(flags & PR_WS)
actual_wd++;
/* if we pad left with ZEROES, do the sign now */
if((flags & (PR_WS | PR_LZ)) ==
(PR_WS | PR_LZ))
{
fn('-', &ptr);
count++;
}
/* pad on left with spaces or zeroes (for right justify) */
EMIT2: if((flags & PR_LJ) == 0)
{
while(given_wd > actual_wd)
{
fn(flags & PR_LZ ? '0' :
' ', &ptr);
count++;
given_wd--;
}
}
/* if we pad left with SPACES, do the sign now */
if((flags & (PR_WS | PR_LZ)) == PR_WS)
{
fn('-', &ptr);
count++;
}
/* emit string/char/converted number */
while(*where != '\0')
{
fn(*where++, &ptr);
count++;
}
/* pad on right with spaces (for left justify) */
if(given_wd < actual_wd)
given_wd = 0;
else given_wd -= actual_wd;
for(; given_wd; given_wd--)
{
fn(' ', &ptr);
count++;
}
break;
default:
break;
}
default:
state = flags = given_wd = 0;
break;
}
}
return count;
}

View File

@ -1,8 +0,0 @@
#ifndef __DO_PRINTF_H__
#define __DO_PRINTF_H__
#include <stdarg.h> /* va_list, va_arg() */
typedef int (*fnptr_t)(unsigned c, void **helper);
int do_printf(const char *fmt, va_list args, fnptr_t fn, void *ptr);
#endif /* __DO_PRINTF_H__ */

View File

@ -1,73 +0,0 @@
#include "uart/uart.h"
#include "rtdef.h"
#include "rtthread.h"
#include <stdio.h>
__attribute__((used))
int fgetc(FILE *stream)
{
int c;
while (!drv_uart_is_kbd_hit()) {
rt_thread_delay(1);
}
c = drv_uart_get_char();
if (c == '\r')
c = '\n';
fputc(c, stream);
return c;
}
__attribute__((used))
char *fgets(char *s, int size, FILE *stream)
{
char *p = s;
int i = 0;
for (i = 0; i < size - 1; i++){
int c = fgetc(stream);
if(c == '\n'){
*p++ = '\n';
break;
}
else if(c == '\0'){
break;
}
else if(c < 0){
return (void*)0;
}
else{
*p++ = c;
}
}
*p = '\0';
return s;
}
__attribute__((used))
int getc(FILE *stream)
{
return fgetc(stream);
}
__attribute__((used))
int getchar(void)
{
return fgetc((void*)0);
}
__attribute__((used))
int ungetc(int c, FILE *stream);

View File

@ -1,520 +0,0 @@
#include <stdio.h>
#include "ndsvfs.h"
#include "dirent.h"
__attribute__((used))
FILE *fopen(const char *path_name, const char *mode)
{
NDSVFS_DENTRY *vde = HAL_NULL;
NDSVFS_FILE *file = HAL_NULL;
UINT32 mode_len;
UINT32 fmode = 0;
UINT32 i;
if (HAL_SUCCESS != _ndsvfs_lock())
return HAL_NULL;
// alloc file object
file = _ndsvfs_alloc_file();
if (file == HAL_NULL)
goto _safe_exit;
// open flags
if (mode == HAL_NULL)
mode_len = 0;
else
mode_len = (UINT32)strlen(mode);
for (i = 0; i < mode_len; ++i)
{
switch (mode[i])
{
case 'r':
fmode |= NDSVFS_FOPEN_READ;
break;
case 'w':
fmode |= NDSVFS_FOPEN_WRITE;
break;
case 'a':
fmode |= NDSVFS_FOPEN_APPEND;
break;
case '+':
fmode |= NDSVFS_FOPEN_PLUS;
break;
}
}
if (fmode == 0)
goto _safe_exit;
#if 0
// (todo) current imp should be read only
if (fmode & ~NDSVFS_FOPEN_READ)
goto _safe_exit;
if (!(fmode & NDSVFS_FOPEN_READ))
goto _safe_exit;
// ~(todo)
#endif
// lookup file entry
if (path_name == HAL_NULL)
goto _safe_exit;
if ((INT)strlen(path_name) == 0)
goto _safe_exit;
vde = _ndsvfs_path_lookup((const char *)path_name);
if (!vde)
{
// (todo) create the file if not exist and flag is not read only
goto _safe_exit;
}
// current imp allows only regular file
// we can open dir now, so I comments the codes
#if 0
if (vde->inode->mode & NDSVFS_INM_ATTR_MASK)
goto _safe_exit;
#endif
// notify file system to open the file
// (todo) call this only when user mode reference to the file is 0.
if (HAL_SUCCESS != vde->sb->open_file(vde, fmode))
goto _safe_exit;
file->flags = fmode;
file->vde = vde;
//file->pos = 0;
//DEBUG(0, 1,"fopen() 0x%08lx\r\n", (UINT32)file);
_ndsvfs_unlock();
// todo
return (FILE *)file;
_safe_exit:
if (vde)
NDSVFS_DEREF(vde);
file->vde = HAL_NULL;
if (file)
NDSVFS_DEREF(file);
_ndsvfs_unlock();
return HAL_NULL;
}
__attribute__((used))
int fclose(FILE *stream)
{
if (stream == HAL_NULL)
return (int)-NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
//DEBUG(0, 1,"fclose() 0x%08lx\r\n", (UINT32)stream);
// (todo) flush the file contents if ever been modified
// notify file system to close the file
// (todo) call this only when user mode reference to the file decreased to 0.
((NDSVFS_FILE *)stream)->vde->sb->close_file(((NDSVFS_FILE *)stream)->vde);
// release file references
if (stream)
NDSVFS_DEREF(stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
size_t fread(void *ptr, size_t size, size_t count, FILE *stream)
{
STATUS status;
UINT32 d_size = (UINT32)size * (UINT32)count;
UINT32 r_size; // size actually been read
#if 1
DEBUG(0, 1,"fread() 0x%08lx ptr(0x%08lx) size(0x%08lx) count(0x%08lx)\r\n",
(UINT32)stream, (UINT32)ptr, (UINT32)size, (UINT32)count);
#endif
if (stream == HAL_NULL)
{
((NDSVFS_FILE *)stream)->err = NDS_VFSD_INVALID_PARAMETER;
return 0;
}
if (HAL_SUCCESS != _ndsvfs_lock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
return 0;
}
DEBUG(0, 1,"fread() 0x%08lx >>\r\n", (UINT32)stream);
if (((NDSVFS_FILE *)stream)->pos < 0)
{
DEBUG(0, 1,"fread() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_START;
return 0;
}
status = ((NDSVFS_FILE *)stream)->vde->sb->read_file(((NDSVFS_FILE *)stream)->vde,
ptr, (UINT32)((NDSVFS_FILE *)stream)->pos, d_size, &r_size);
if (status == NDS_VFSD_END_OF_FILE)
{
((NDSVFS_FILE *)stream)->eof = HAL_TRUE;
status = HAL_SUCCESS;
}
if (status == HAL_SUCCESS)
((NDSVFS_FILE *)stream)->pos += (INT32)r_size;
else
r_size = 0;
DEBUG(0, 1,"fread() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
DEBUG(0, 1,"fread() 0x%08lx << unlock fail\r\n", (UINT32)stream);
return 0;
}
return (int)((size_t)r_size / size);
}
__attribute__((used))
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
{
STATUS status;
UINT32 d_size = (UINT32)size * (UINT32)count;
UINT32 w_size; // size actually been write
#if 1
DEBUG(0, 1,"fwrite() 0x%08lx ptr(0x%08lx) size(0x%08lx) count(0x%08lx)\r\n",
(UINT32)stream, (UINT32)ptr, (UINT32)size, (UINT32)count);
#endif
if (stream == HAL_NULL)
{
((NDSVFS_FILE *)stream)->err = NDS_VFSD_INVALID_PARAMETER;
return 0;
}
if (HAL_SUCCESS != _ndsvfs_lock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
return 0;
}
DEBUG(0, 1,"fwrite() 0x%08lx >>\r\n", (UINT32)stream);
if (((NDSVFS_FILE *)stream)->pos < 0)
{
DEBUG(0, 1,"fwrite() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_START;
return 0;
}
status = ((NDSVFS_FILE *)stream)->vde->sb->write_file(((NDSVFS_FILE *)stream)->vde,
ptr, (UINT32)((NDSVFS_FILE *)stream)->pos, d_size, &w_size);
if (status == NDS_VFSD_END_OF_FILE)
{
((NDSVFS_FILE *)stream)->eof = HAL_TRUE;
status = HAL_SUCCESS;
}
if (status == HAL_SUCCESS)
((NDSVFS_FILE *)stream)->pos += (INT32)w_size;
else
w_size = 0;
DEBUG(0, 1,"fwrite() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
DEBUG(0, 1,"fwrite() 0x%08lx << unlock fail\r\n", (UINT32)stream);
return 0;
}
return (int)((size_t)w_size / size);
}
__attribute__((used))
int fflush(FILE *stream)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
// todo
return (int)HAL_SUCCESS;
}
__attribute__((used))
int fseek(FILE *stream, int offset, int origin)
{
INT32 pos;
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
pos = ((NDSVFS_FILE *)stream)->pos;
//DEBUG(0, 1,"fseek() 0x%08lx >>\r\n", (UINT32)stream);
//DEBUG(0, 1,"pos (cur) : 0x%08lx\r\n", pos);
//DEBUG(0, 1,"offset : 0x%08lx\r\n", offset);
switch (origin)
{
case FSEEK_CUR:
pos += offset;
break;
case FSEEK_END:
pos = (INT32)((NDSVFS_FILE *)stream)->vde->inode->size + offset;
break;
case FSEEK_SET:
pos = offset;
break;
default:
//DEBUG(0, 1,"fseek() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER;
}
//DEBUG(0, 1,"pos (new) : 0x%08lx\r\n", pos);
/*
if (pos > ((NDSVFS_FILE *)stream)->vde->inode->size)
{
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER; // todo: might be a valid condition for write-mode
}*/
((NDSVFS_FILE *)stream)->pos = pos;
//DEBUG(0, 1,"fseek() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
long ftell(FILE *stream)
{
long pos;
if (stream == HAL_NULL)
return (int)HAL_ERR_INVALID_OPERATION;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
pos = (long)((NDSVFS_FILE *)stream)->pos;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return pos;
}
void frewind(FILE *stream)
{
if (stream == HAL_NULL)
return;
if (HAL_SUCCESS != _ndsvfs_lock())
return;
((NDSVFS_FILE *)stream)->pos = 0;
((NDSVFS_FILE *)stream)->err = 0;
((NDSVFS_FILE *)stream)->eof = 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return;
}
__attribute__((used))
int fgetpos(FILE *stream, fpos_t *position)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (position == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
*position = ((NDSVFS_FILE *)stream)->pos;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
int fsetpos(FILE *stream, const fpos_t *position)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (position == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
if (*position > (INT32)((NDSVFS_FILE *)stream)->vde->inode->size)
{
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER; // todo: might be a valid condition for write-mode
}
((NDSVFS_FILE *)stream)->pos = *position;
((NDSVFS_FILE *)stream)->eof = 0; // ?? todo: signal eof if position reaches end of file?
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
int feof(FILE *stream)
{
UINT32 eof;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
eof = ((NDSVFS_FILE *)stream)->eof > 0 ? HAL_TRUE : HAL_FALSE;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return eof;
}
__attribute__((used))
int ferror(FILE *stream)
{
UINT32 err;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
err = ((NDSVFS_FILE *)stream)->err > 0 ? 1 : 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return err;
}
void fclearerr(FILE *stream)
{
if (HAL_SUCCESS != _ndsvfs_lock())
return;
((NDSVFS_FILE *)stream)->err = 0;
((NDSVFS_FILE *)stream)->eof = 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return;
}
extern STATUS _ndsvfs_read_dirs(NDSVFS_DENTRY *vde_parent, NDSVFS_DENTRY **vde_list);
__attribute__((used))
struct dir *opendir(const char *path)
{
NDSVFS_FILE *file = NULL;
struct dir *dirp = NULL;
int status;
file = (NDSVFS_FILE *)fopen(path, "rb");
if (file == NULL) {
// ERROR("fopen path=%s\n",path);
return (void*)0;
}
if (!S_ISDIR(file->vde->inode)){
fclose((FILE *)file);
// ERROR("Not a dir path=%s\n",path);
return (void*)0;
}
if (!file->dirp){
file->dirp = malloc(sizeof(struct dir));
KASSERT(file->dirp);
dirp = (struct dir*)file->dirp;
dirp->d_dirent = malloc(sizeof(struct dirent));
KASSERT(dirp->d_dirent);
dirp->d_file = file;
dirp->d_off = 0;
}
status = _ndsvfs_read_dirs(file->vde, &(dirp->vde_list));
dirp->vde_head = dirp->vde_list;
dirp->vde_list = NULL;
if(status == HAL_FAILURE)
return HAL_NULL;
return dirp;
}
__attribute__((used))
int closedir(struct dir *dirp)
{
NDSVFS_FILE *file = dirp->d_file;
if (dirp == NULL)
return -1;
if (file == NULL)
return -1;
if (dirp->d_dirent != NULL)
free(dirp->d_dirent);
free(dirp);
return fclose((FILE *)file);
}
__attribute__((used))
struct dirent *readdir(struct dir *dirp)
{
/* this is the first time, becasue the vde_list is pointed to null */
if (dirp->vde_list == NULL && dirp->vde_head != NULL) {
strcpy(dirp->d_dirent->d_name, dirp->vde_head->name.utf_name);
dirp->vde_list = NDS_LIST_ENTITY(dirp->vde_head->c_chain.next, NDSVFS_DENTRY, c_chain);
return dirp->d_dirent;
}
/* this is not the first time. */
else if (dirp->vde_list != dirp->vde_head) {
strcpy(dirp->d_dirent->d_name, dirp->vde_list->name.utf_name);
dirp->vde_list = NDS_LIST_ENTITY(dirp->vde_list->c_chain.next, NDSVFS_DENTRY, c_chain);
return dirp->d_dirent;
}
else
return NULL;
}
__attribute__((used))
int fstat(FILE* fd, struct stat *buf)
{
NDSVFS_FILE *file = (NDSVFS_FILE *)fd;
if (file == HAL_NULL)
return -1;
return file->vde->sb->stat_file(file->vde, buf);
}

View File

@ -1,14 +0,0 @@
#include <stdio.h>
__attribute__((used))
int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vprintf(fmt, args);
va_end(args);
return ret_val;
}

View File

@ -1,41 +0,0 @@
#include "uart/uart.h"
#include <stdio.h>
__attribute__((used))
int fputc(int c, FILE *stream)
{
if (c == '\n')
drv_uart_put_char('\r');
drv_uart_put_char(c);
return c;
}
__attribute__((used))
int fputs(const char *s, FILE *stream)
{
while (fputc(*s++, stream))
;
return 0;
}
__attribute__((used))
int putc(int c, FILE *stream)
{
return fputc(c, stream);
}
__attribute__((used))
int putchar(int c)
{
return fputc(c, (void*)0x10);
}
__attribute__((used))
int puts(const char *s)
{
return fputs(s, (void*)0x10);
}

View File

@ -1,65 +0,0 @@
#include <stdarg.h> /* va_list, va_arg() */
#include <stdio.h>
#include "do_printf.h"
/*****************************************************************************
* PRINTF You must write your own putchar()
*****************************************************************************/
static int vprintf_help(unsigned c, void **ptr){
ptr = ptr; /* to avoid unused varible warning */
putchar(c);
return 0;
}
static int vsprintf_help(unsigned int c, void **ptr){
char *dst = *ptr;
*dst++ = c;
*ptr = dst;
return 0 ;
}
__attribute__((used))
int vsprintf(char *buffer, const char *fmt, va_list args){
int ret_val = do_printf(fmt, args, vsprintf_help, (void *)buffer);
buffer[ret_val] = '\0';
return ret_val;
}
__attribute__((used))
int sprintf(char *buffer, const char *fmt, ...){
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vsprintf(buffer, fmt, args);
va_end(args);
return ret_val;
}
__attribute__((used))
int vprintf(const char *fmt, va_list args){
return do_printf(fmt, args, vprintf_help, (void *)0);
}
__attribute__((used))
int printf(const char *fmt, ...){
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vprintf(fmt, args);
va_end(args);
return ret_val;
}

View File

@ -1 +0,0 @@
lib-y += qsort.o

View File

@ -1,149 +0,0 @@
//
// qsort.c
//
// Quick sort
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// 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. Neither the name of the project 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.
//
#define CUTOFF 8
static void shortsort(char *lo, char *hi, unsigned width, int (*comp)(const void *, const void *));
static void swap(char *p, char *q, unsigned int width);
__attribute__((used))
void qsort(void *base, unsigned num, unsigned width, int (*comp)(const void *, const void *))
{
char *lo, *hi;
char *mid;
char *loguy, *higuy;
unsigned size;
char *lostk[30], *histk[30];
int stkptr;
if (num < 2 || width == 0) return;
stkptr = 0;
lo = base;
hi = (char *) base + width * (num - 1);
recurse:
size = (hi - lo) / width + 1;
if (size <= CUTOFF)
{
shortsort(lo, hi, width, comp);
}
else
{
mid = lo + (size / 2) * width;
swap(mid, lo, width);
loguy = lo;
higuy = hi + width;
for (;;)
{
do { loguy += width; } while (loguy <= hi && comp(loguy, lo) <= 0);
do { higuy -= width; } while (higuy > lo && comp(higuy, lo) >= 0);
if (higuy < loguy) break;
swap(loguy, higuy, width);
}
swap(lo, higuy, width);
if (higuy - 1 - lo >= hi - loguy)
{
if (lo + width < higuy)
{
lostk[stkptr] = lo;
histk[stkptr] = higuy - width;
++stkptr;
}
if (loguy < hi)
{
lo = loguy;
goto recurse;
}
}
else
{
if (loguy < hi)
{
lostk[stkptr] = loguy;
histk[stkptr] = hi;
++stkptr;
}
if (lo + width < higuy)
{
hi = higuy - width;
goto recurse;
}
}
}
--stkptr;
if (stkptr >= 0)
{
lo = lostk[stkptr];
hi = histk[stkptr];
goto recurse;
}
else
return;
}
static void shortsort(char *lo, char *hi, unsigned width, int (*comp)(const void *, const void *))
{
char *p, *max;
while (hi > lo)
{
max = lo;
for (p = lo+width; p <= hi; p += width) if (comp(p, max) > 0) max = p;
swap(max, hi, width);
hi -= width;
}
}
static void swap(char *a, char *b, unsigned width)
{
char tmp;
if (a != b)
{
while (width--)
{
tmp = *a;
*a++ = *b;
*b++ = tmp;
}
}
}

View File

@ -1,12 +0,0 @@
lib-y += memcpy.o
lib-y += memmove.o
lib-y += memset.o
lib-y += strcat.o
lib-y += strcasecmp.o
lib-y += strcmp.o
lib-y += strdup.o
lib-y += strlen.o
lib-y += strstr.o
lib-y += strtoul.o
lib-y += strupr.o
lib-y += wchar.o

View File

@ -1,10 +0,0 @@
#include <string.h>
__attribute__((used))
void *memcpy(void *dest, const void *src, size_t n)
{
while (n--)
*(unsigned char *)dest++ = *(const unsigned char *)src++;
return dest;
}

View File

@ -1,17 +0,0 @@
#include <string.h>
__attribute__((used))
void *memmove(void *dest, const void *src, size_t n)
{
char *destp = dest;
const char *srcp = src;
if (srcp < destp)
while (n--)
destp[n] = srcp[n];
else
while (n--)
*destp++ = *srcp++;
return dest;
}

View File

@ -1,10 +0,0 @@
#include <string.h>
__attribute__((used))
void *memset(void *s, int c, size_t n)
{
while (n--)
*(unsigned char *)s++ = c;
return s;
}

View File

@ -1,30 +0,0 @@
#include <string.h>
__attribute__((used))
int strcasecmp(const char *s1, const char *s2)
{
while (*s1 == *s2 || (*s1 ^ 0x20) == *s2) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
__attribute__((used))
int strncasecmp(const char *s1, const char *s2, size_t n)
{
while ((*s1 == *s2 || (*s1 ^ 0x20) == *s2) && --n) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}

View File

@ -1,33 +0,0 @@
#include <string.h>
__attribute__((used))
char *strcat(char *dest, const char *src)
{
char *destp = dest;
while (*destp)
destp++;
while (*src)
*destp++ = *src++;
*destp = '\0';
return dest;
}
__attribute__((used))
char *strncat(char *dest, const char *src, size_t n)
{
char *destp = dest;
while (*destp)
destp++;
while (*src && n--)
*destp++ = *src++;
*destp = '\0';
return dest;
}

View File

@ -1,30 +0,0 @@
#include <string.h>
__attribute__((used))
int strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
__attribute__((used))
int strncmp(const char *s1, const char *s2, size_t n)
{
while (*s1 == *s2 && --n) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}

View File

@ -1,30 +0,0 @@
#include <string.h>
__attribute__((used))
char *strcpy(char *dest, const void *src)
{
char *destp = dest;
char *srcp = (char *)src;
while (*srcp)
*destp++ = *srcp++;
*destp = '\0';
return dest;
}
__attribute__((used))
char *strncpy(char *dest, const void *src, size_t n)
{
char *destp = dest;
char *srcp = (char *)src;
while (*srcp && n--)
*destp++ = *srcp++;
if (n)
*destp = '\0';
return dest;
}

View File

@ -1,32 +0,0 @@
#include <string.h>
#include <stdlib.h>
__attribute__((used))
char *strdup(const char *s)
{
int len = strlen(s);
char *buf = malloc(len + 1);
if (buf) {
strncpy(buf, s, len);
buf[len] = '\0';
}
return buf;
}
__attribute__((used))
char *strndup(const char *s, size_t n)
{
int len = strnlen(s, n);
char *buf = malloc(len + 1);
if (buf) {
strncpy(buf, s, len);
buf[len] = '\0';
}
return buf;
}

View File

@ -1,23 +0,0 @@
#include <string.h>
__attribute__((used))
size_t strlen(const char *s)
{
size_t n = 0;
while (*s++)
n++;
return n;
}
__attribute__((used))
size_t strnlen(const char *s, size_t maxlen)
{
size_t n = 0;
while (*s++ && maxlen--)
n++;
return n;
}

View File

@ -1,45 +0,0 @@
#include <string.h>
/* FIXME: LICENSE */
__attribute__((used))
char *strstr(const char *haystack, const char *needle)
{
const char *start_s1 = (void *)0;
const char *in_s2 = (void *)0;
for (; *haystack != '\0'; haystack++) {
if (!start_s1) {
/* first char of match */
if (*haystack == *needle) {
/* remember start of matching substring in haystack */
start_s1 = haystack;
in_s2 = needle + 1;
/* done already? */
if (*in_s2 == '\0')
return (char*)start_s1;
}
/* continued mis-match
else
nothing ; */
}
else {
/* continued match */
if (*haystack == *in_s2) {
in_s2++;
/* done */
if (*in_s2 == '\0')
return (char*)start_s1;
}
else
/* first char of mis-match */
start_s1 = (void *)0;
}
}
return (void *)0;
}

View File

@ -1,82 +0,0 @@
#include <string.h>
#include <ctype.h>
/* FIXME: LICENSE */
__attribute__((used))
unsigned long int strtoul(const char *nptr, char **endptr, int base)
{
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
s = nptr;
do
c = *s++;
while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
}
else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
#ifndef ULONG_MAX
#define ULONG_MAX (unsigned long) -1
#endif
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = ULONG_MAX % (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0)
continue;
// FIXME
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = ULONG_MAX;
}
else {
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = (char *)(any ? s - 1 : nptr);
return acc;
}

View File

@ -1,16 +0,0 @@
#include <string.h>
__attribute__((used))
char *strupr(char *str)
{
char *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter >= 'a') && (*str_iter <= 'z'))
*str_iter -= 0x20;
++str_iter;
}
return str;
}

View File

@ -1,147 +0,0 @@
#include <string.h>
__attribute__((used))
wchar_t *wcscat(wchar_t *str_dst, const wchar_t *str_src)
{
wchar_t *dst_iter = str_dst;
int i = 0;
while (*dst_iter != 0)
++dst_iter;
while (str_src[i] != 0)
{
dst_iter[i] = str_src[i];
++i;
}
dst_iter[i] = 0;
return str_dst;
}
__attribute__((used))
int wcscmp(const wchar_t *string1, const wchar_t *string2)
{
int i = 0;
register wchar_t c1, c2;
while (1)
{
c1 = string1[i];
c2 = string2[i];
if (c1 < c2)
{
return -1;
}
else if (c1 > c2)
{
return 1;
}
if ((c1 == 0) || (c2 == 0))
break;
++i;
}
return 0;
}
__attribute__((used))
int wcsncmp(const wchar_t *string1, const wchar_t *string2, int count)
{
int i = 0;
while (i < count)
{
if (string1[i] < string2[i])
{
return -1;
}
else if (string1[i] > string2[i])
{
return 1;
}
if ((string1[i] == 0) || (string2[i] == 0))
break;
++i;
}
return 0;
}
__attribute__((used))
wchar_t *wcscpy(wchar_t *str_dst, const wchar_t *str_src)
{
int i = 0;
while (str_src[i] != 0)
{
str_dst[i] = str_src[i];
++i;
}
str_dst[i] = 0;
return str_dst;
}
__attribute__((used))
wchar_t *wcsncpy(wchar_t *str_dst, const wchar_t *str_src, int count)
{
int i = 0;
while ((str_src[i] != 0) && (i < count))
{
str_dst[i] = str_src[i];
++i;
}
str_dst[i] = 0;
return str_dst;
}
__attribute__((used))
int wcslen(const wchar_t *str)
{
int i = 0;
while (str[i] != 0)
++i;
return i;
}
__attribute__((used))
wchar_t *wcsupr(wchar_t *str)
{
wchar_t *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter >= (wchar_t)'a') && (*str_iter <= (wchar_t)'z'))
*str_iter -= 0x0020;
++str_iter;
}
return str;
}
__attribute__((used))
wchar_t *wcslwr(wchar_t *str)
{
wchar_t *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter <= (wchar_t)'Z') && (*str_iter >= (wchar_t)'A'))
*str_iter += 0x0020;
++str_iter;
}
return str;
}

View File

@ -5,7 +5,7 @@ E-Mail : Archer Zhang <archer.zhang@wh-mx.com>
******************************
[1] 在bsp目录下添加AE210P目录这是Andes AE210P EVBN1068A的主目录
[2] 在libcpu目录下添加nds32目录这是Andes N10系列Core的体系目录
[3] 由于编译器和Libc的原因我们使用的Libc位于AE210P/libc修改了finsh.h文件的Line7475如下
[3] 由于编译器的原因修改了finsh.h文件的Line7475如下
#if !(defined(__GNUC__) && defined(__x86_64__))
//typedef unsigned int size_t; // 注释这个typedef
#include <stddef.h> // 添加两个头文件包含

View File

@ -1,33 +0,0 @@
#ifndef OS_CPU_H
#define OS_CPU_H
#include "nds32.h"
/*
* *********************************************************************************************************
* * DATA TYPES
* * (Compiler Specific)
* *********************************************************************************************************
* */
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned long OS_STK; /* Each stack entry is 32-bit wide */
typedef unsigned long OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
void OS_CPU_IRQ_ISR(void); /* See OS_CPU_A.S */
void OS_CPU_IRQ_ISR_Handler(void); /* See BSP code */
void OSCtxSw(void);
void CtxSave(void);
void CtxRestore(void);
void OS_DCache_Writeback(void *aVA, unsigned aSize);
#endif