forked from xuos/xiuos
Support smp. TODO: delete all inner kernel locks.
This commit is contained in:
parent
892613a0d5
commit
d987bf0357
|
@ -74,7 +74,7 @@ Modification:
|
||||||
|
|
||||||
#include "cortex_a9.h"
|
#include "cortex_a9.h"
|
||||||
|
|
||||||
#define NR_CPU 1
|
#define NR_CPU 4
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline uint32_t user_mode()
|
__attribute__((always_inline)) static inline uint32_t user_mode()
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,15 +232,15 @@ static struct DCacheDone dcache_done = {
|
||||||
struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag)
|
struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag)
|
||||||
{
|
{
|
||||||
/* init icache */
|
/* init icache */
|
||||||
icache_done.enable();
|
// icache_done.enable();
|
||||||
// icache_done.disable();
|
icache_done.disable();
|
||||||
return &icache_done;
|
return &icache_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag)
|
struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag)
|
||||||
{
|
{
|
||||||
/* init dcache */
|
/* init dcache */
|
||||||
dcache_done.enable();
|
// dcache_done.enable();
|
||||||
// dcache_done.disable();
|
dcache_done.disable();
|
||||||
return &dcache_done;
|
return &dcache_done;
|
||||||
}
|
}
|
|
@ -447,11 +447,9 @@ bool tracer_delete_trace(struct TraceTag* target, struct TraceTag* owner)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct spinlock ac_tracer_lock;
|
|
||||||
void tracer_init(void)
|
void tracer_init(void)
|
||||||
{
|
{
|
||||||
/* init sys_tracer, the manager */
|
/* init sys_tracer, the manager */
|
||||||
spinlock_init(&ac_tracer_lock, "tracerlock");
|
|
||||||
spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap");
|
spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap");
|
||||||
spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap");
|
spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap");
|
||||||
memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock));
|
memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock));
|
||||||
|
|
|
@ -32,31 +32,31 @@ all: init test_fs simple_client simple_server shell fs_server test_priority read
|
||||||
bin:
|
bin:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
|
|
||||||
shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o
|
shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o
|
init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o
|
test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o
|
simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o
|
simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o
|
fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
test_priority: test_priority.o libserial.o usyscall.o
|
test_priority: test_priority.o libserial.o usyscall.o libmem.o
|
||||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||||
@${objdump} -S $@ > $@.asm
|
@${objdump} -S $@ > $@.asm
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ int main(int argc, char* argv[])
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) {
|
if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
|
||||||
printf("Syscall Spawn shell failed\n");
|
printf("Syscall Spawn shell failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,10 @@ int main(int argc, char** argv)
|
||||||
itoa(id - 1, id_buf, 10);
|
itoa(id - 1, id_buf, 10);
|
||||||
char* shell_task_param[3] = { "/simple_client", id_buf, 0 };
|
char* shell_task_param[3] = { "/simple_client", id_buf, 0 };
|
||||||
if ((fd = open(&session, shell_task_param[0])) >= 0) {
|
if ((fd = open(&session, shell_task_param[0])) >= 0) {
|
||||||
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) {
|
if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
|
||||||
printf("Syscall Spawn simple_client failed\n");
|
printf("Syscall Spawn simple_client failed\n");
|
||||||
}
|
}
|
||||||
if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) {
|
if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
|
||||||
printf("Syscall Spawn simple_client failed\n");
|
printf("Syscall Spawn simple_client failed\n");
|
||||||
}
|
}
|
||||||
close(&session, fd);
|
close(&session, fd);
|
||||||
|
|
|
@ -13,8 +13,8 @@ cflags = -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=so
|
||||||
c_useropts = -O0
|
c_useropts = -O0
|
||||||
|
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
|
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
-I$(KERNEL_ROOT)/services/app
|
-I$(KERNEL_ROOT)/services/app
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
#include "usyscall.h"
|
#include "usyscall.h"
|
||||||
|
#include "libmem.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
||||||
|
@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv)
|
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
|
||||||
{
|
{
|
||||||
struct KernReadTool read_tool = {
|
int file_size = ipc_fsize(session, fd);
|
||||||
.session = session,
|
void* img = malloc(file_size);
|
||||||
.fd = fd,
|
int read_len = 0, cur_read_len = 0;
|
||||||
.ipc_read = ipc_read,
|
while (read_len < file_size) {
|
||||||
};
|
cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096;
|
||||||
return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0);
|
read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len);
|
||||||
|
}
|
||||||
|
int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0);
|
||||||
|
free(img);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exit()
|
int exit()
|
||||||
|
|
|
@ -51,15 +51,10 @@ typedef union {
|
||||||
} sys_state_info;
|
} sys_state_info;
|
||||||
|
|
||||||
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
||||||
|
typedef int (*ipc_fsize_fn)(struct Session* session, int fd);
|
||||||
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
||||||
|
|
||||||
struct KernReadTool {
|
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
|
||||||
struct Session* session;
|
|
||||||
int fd;
|
|
||||||
ipc_read_fn ipc_read;
|
|
||||||
};
|
|
||||||
|
|
||||||
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv);
|
|
||||||
int exit();
|
int exit();
|
||||||
int yield();
|
int yield();
|
||||||
int register_server(char* name);
|
int register_server(char* name);
|
||||||
|
|
|
@ -18,6 +18,7 @@ c_useropts = -O0
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
|
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
-I$(KERNEL_ROOT)/services/app
|
-I$(KERNEL_ROOT)/services/app
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
#include "usyscall.h"
|
#include "usyscall.h"
|
||||||
|
#include "libmem.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
||||||
|
@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv)
|
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv)
|
||||||
{
|
{
|
||||||
struct KernReadTool read_tool = {
|
int file_size = ipc_fsize(session, fd);
|
||||||
.session = session,
|
void* img = malloc(file_size);
|
||||||
.fd = fd,
|
int read_len = 0, cur_read_len = 0;
|
||||||
.ipc_read = ipc_read,
|
while (read_len < file_size) {
|
||||||
};
|
cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096;
|
||||||
return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0);
|
read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len);
|
||||||
|
}
|
||||||
|
int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0);
|
||||||
|
free(img);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exit()
|
int exit()
|
||||||
|
|
|
@ -51,15 +51,10 @@ typedef union {
|
||||||
} sys_state_info;
|
} sys_state_info;
|
||||||
|
|
||||||
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
||||||
|
typedef int (*ipc_fsize_fn)(struct Session* session, int fd);
|
||||||
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
||||||
|
|
||||||
struct KernReadTool {
|
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
|
||||||
struct Session* session;
|
|
||||||
int fd;
|
|
||||||
ipc_read_fn ipc_read;
|
|
||||||
};
|
|
||||||
|
|
||||||
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv);
|
|
||||||
int exit();
|
int exit();
|
||||||
int yield();
|
int yield();
|
||||||
int register_server(char* name);
|
int register_server(char* name);
|
||||||
|
|
|
@ -18,6 +18,7 @@ c_useropts = -O0
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
|
-I$(KERNEL_ROOT)/services/fs/fs_server/include \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
-I$(KERNEL_ROOT)/services/app
|
-I$(KERNEL_ROOT)/services/app
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ int IPC_DO_SERVE_FUNC(Ipc_read)(int* fd, char* dst, int* offset, int* len)
|
||||||
|
|
||||||
int cur_read_len = InodeRead(ip, dst, *offset, *len);
|
int cur_read_len = InodeRead(ip, dst, *offset, *len);
|
||||||
|
|
||||||
return *len;
|
return cur_read_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len)
|
int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len)
|
||||||
|
@ -305,18 +305,36 @@ int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len)
|
||||||
return cur_write_len;
|
return cur_write_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IPC_DO_SERVE_FUNC(Ipc_fsize)(int* fd)
|
||||||
|
{
|
||||||
|
struct FileDescriptor* fdp = GetFileDescriptor(*fd);
|
||||||
|
if (!fdp) {
|
||||||
|
printf("read: fd invalid\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Inode* ip = fdp->data;
|
||||||
|
if (ip->type != FS_FILE) {
|
||||||
|
printf("read: %s Is not a file\n", fdp->path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip->size;
|
||||||
|
}
|
||||||
|
|
||||||
IPC_SERVER_INTERFACE(Ipc_ls, 1);
|
IPC_SERVER_INTERFACE(Ipc_ls, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_cd, 1);
|
IPC_SERVER_INTERFACE(Ipc_cd, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_mkdir, 1);
|
IPC_SERVER_INTERFACE(Ipc_mkdir, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_delete, 1);
|
IPC_SERVER_INTERFACE(Ipc_delete, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_cat, 1);
|
IPC_SERVER_INTERFACE(Ipc_cat, 1);
|
||||||
|
IPC_SERVER_INTERFACE(Ipc_fsize, 1);
|
||||||
|
|
||||||
IPC_SERVER_INTERFACE(Ipc_open, 1);
|
IPC_SERVER_INTERFACE(Ipc_open, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_close, 1);
|
IPC_SERVER_INTERFACE(Ipc_close, 1);
|
||||||
IPC_SERVER_INTERFACE(Ipc_read, 4);
|
IPC_SERVER_INTERFACE(Ipc_read, 4);
|
||||||
IPC_SERVER_INTERFACE(Ipc_write, 4);
|
IPC_SERVER_INTERFACE(Ipc_write, 4);
|
||||||
|
|
||||||
IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9,
|
IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 10,
|
||||||
Ipc_ls,
|
Ipc_ls,
|
||||||
Ipc_cd,
|
Ipc_cd,
|
||||||
Ipc_mkdir,
|
Ipc_mkdir,
|
||||||
|
@ -325,7 +343,8 @@ IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9,
|
||||||
Ipc_open,
|
Ipc_open,
|
||||||
Ipc_close,
|
Ipc_close,
|
||||||
Ipc_read,
|
Ipc_read,
|
||||||
Ipc_write);
|
Ipc_write,
|
||||||
|
Ipc_fsize);
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@ c_useropts = -O0
|
||||||
|
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
-I$(KERNEL_ROOT)/services/app
|
-I$(KERNEL_ROOT)/services/app
|
||||||
|
|
||||||
|
|
|
@ -63,4 +63,10 @@ IPC_INTERFACE(Ipc_write, 4, fd, src, offset, len, sizeof(int), *(int*)len, sizeo
|
||||||
int write(struct Session* session, int fd, char* src, int offset, int len)
|
int write(struct Session* session, int fd, char* src, int offset, int len)
|
||||||
{
|
{
|
||||||
return IPC_CALL(Ipc_write)(session, &fd, src, &offset, &len);
|
return IPC_CALL(Ipc_write)(session, &fd, src, &offset, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC_INTERFACE(Ipc_fsize, 1, fd, sizeof(int));
|
||||||
|
int fsize(struct Session* session, int fd)
|
||||||
|
{
|
||||||
|
return IPC_CALL(Ipc_fsize)(session, &fd);
|
||||||
}
|
}
|
|
@ -15,13 +15,14 @@
|
||||||
#include "libipc.h"
|
#include "libipc.h"
|
||||||
|
|
||||||
IPC_SERVICES(IpcFsServer, Ipc_ls, Ipc_cd, Ipc_mkdir, Ipc_delete, Ipc_cat,
|
IPC_SERVICES(IpcFsServer, Ipc_ls, Ipc_cd, Ipc_mkdir, Ipc_delete, Ipc_cat,
|
||||||
Ipc_open, Ipc_close, Ipc_read, Ipc_write);
|
Ipc_open, Ipc_close, Ipc_read, Ipc_write, Ipc_fsize);
|
||||||
|
|
||||||
int ls(struct Session* session, char* path);
|
int ls(struct Session* session, char* path);
|
||||||
int cd(struct Session* session, char* path);
|
int cd(struct Session* session, char* path);
|
||||||
int mkdir(struct Session* session, char* path);
|
int mkdir(struct Session* session, char* path);
|
||||||
int rm(struct Session* session, char* path);
|
int rm(struct Session* session, char* path);
|
||||||
int cat(struct Session* session, char* path);
|
int cat(struct Session* session, char* path);
|
||||||
|
int fsize(struct Session* session, int fd);
|
||||||
|
|
||||||
int open(struct Session* session, char* path);
|
int open(struct Session* session, char* path);
|
||||||
int close(struct Session* session, int fd);
|
int close(struct Session* session, int fd);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SRC_DIR := ipc
|
SRC_DIR := ipc memory
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ objdump = ${toolchain}objdump
|
||||||
|
|
||||||
c_useropts = -O0
|
c_useropts = -O0
|
||||||
|
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
|
INC_DIR = -I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
-I$(KERNEL_ROOT)/services/app
|
-I$(KERNEL_ROOT)/services/app
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,14 @@ user_ldflags = -N -Ttext 0
|
||||||
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
|
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
|
||||||
c_useropts = -O0
|
c_useropts = -O0
|
||||||
|
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/app \
|
INC_DIR = -I$(KERNEL_ROOT)/services/app \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/ipc
|
||||||
|
|
||||||
all:
|
all: libmem.o
|
||||||
|
@mv $^ ../../app
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
@echo "cc $^"
|
@echo "cc $^"
|
||||||
|
|
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
* mm.c - malloc using segregated list
|
||||||
|
* KAIST
|
||||||
|
* Tony Kim
|
||||||
|
*
|
||||||
|
* In this approach,
|
||||||
|
* Every block has a header and a footer
|
||||||
|
* in which header contains reallocation information, size, and allocation info
|
||||||
|
* and footer contains size and allocation info.
|
||||||
|
* Free list are tagged to the segregated list.
|
||||||
|
* Therefore all free block contains pointer to the predecessor and successor.
|
||||||
|
* The segregated list headers are organized by 2^k size.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libmem.h"
|
||||||
|
#include "usyscall.h"
|
||||||
|
|
||||||
|
/* single word (4) or double word (8) alignment */
|
||||||
|
#define ALIGNMENT 8
|
||||||
|
/* rounds up to the nearest multiple of ALIGNMENT */
|
||||||
|
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~0x7)
|
||||||
|
|
||||||
|
// My additional Macros
|
||||||
|
#define WSIZE 4 // word and header/footer size (bytes)
|
||||||
|
#define DSIZE 8 // double word size (bytes)
|
||||||
|
#define INITCHUNKSIZE (1 << 6)
|
||||||
|
#define CHUNKSIZE (1 << 12) //+(1<<7)
|
||||||
|
|
||||||
|
#define LISTLIMIT 20
|
||||||
|
|
||||||
|
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
// Pack a size and allocated bit into a word
|
||||||
|
#define PACK(size, alloc) ((size) | (alloc))
|
||||||
|
|
||||||
|
// Read and write a word at address p
|
||||||
|
#define GET(p) (*(unsigned int*)(p))
|
||||||
|
#define PUT(p, val) (*(unsigned int*)(p) = (val) | GET_TAG(p))
|
||||||
|
#define PUT_NOTAG(p, val) (*(unsigned int*)(p) = (val))
|
||||||
|
|
||||||
|
// Store predecessor or successor pointer for free blocks
|
||||||
|
#define SET_PTR(p, ptr) (*(unsigned int*)(p) = (unsigned int)(ptr))
|
||||||
|
|
||||||
|
// Read the size and allocation bit from address p
|
||||||
|
#define GET_SIZE(p) (GET(p) & ~0x7)
|
||||||
|
#define GET_ALLOC(p) (GET(p) & 0x1)
|
||||||
|
#define GET_TAG(p) (GET(p) & 0x2)
|
||||||
|
#define SET_RATAG(p) (GET(p) |= 0x2)
|
||||||
|
#define REMOVE_RATAG(p) (GET(p) &= ~0x2)
|
||||||
|
|
||||||
|
// Address of block's header and footer
|
||||||
|
#define HDRP(ptr) ((char*)(ptr)-WSIZE)
|
||||||
|
#define FTRP(ptr) ((char*)(ptr) + GET_SIZE(HDRP(ptr)) - DSIZE)
|
||||||
|
|
||||||
|
// Address of (physically) next and previous blocks
|
||||||
|
#define NEXT_BLKP(ptr) ((char*)(ptr) + GET_SIZE((char*)(ptr)-WSIZE))
|
||||||
|
#define PREV_BLKP(ptr) ((char*)(ptr)-GET_SIZE((char*)(ptr)-DSIZE))
|
||||||
|
|
||||||
|
// Address of free block's predecessor and successor entries
|
||||||
|
#define PRED_PTR(ptr) ((char*)(ptr))
|
||||||
|
#define SUCC_PTR(ptr) ((char*)(ptr) + WSIZE)
|
||||||
|
|
||||||
|
// Address of free block's predecessor and successor on the segregated list
|
||||||
|
#define PRED(ptr) (*(char**)(ptr))
|
||||||
|
#define SUCC(ptr) (*(char**)(SUCC_PTR(ptr)))
|
||||||
|
|
||||||
|
// End of my additional macros
|
||||||
|
|
||||||
|
// Global var
|
||||||
|
void* segregated_free_lists[LISTLIMIT];
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void* extend_heap(size_t size);
|
||||||
|
static void* coalesce(void* ptr);
|
||||||
|
static void* place(void* ptr, size_t asize);
|
||||||
|
static void insert_node(void* ptr, size_t size);
|
||||||
|
static void delete_node(void* ptr);
|
||||||
|
|
||||||
|
static uintptr_t userland_heap_base;
|
||||||
|
static uintptr_t userland_heap_top;
|
||||||
|
static uintptr_t requested_heap_size;
|
||||||
|
|
||||||
|
static void* mem_sbrk(size_t size)
|
||||||
|
{
|
||||||
|
uintptr_t userland_heap_size = userland_heap_top - userland_heap_base;
|
||||||
|
if (userland_heap_size - requested_heap_size >= size) {
|
||||||
|
void* ret_ptr = (void*)(userland_heap_base + requested_heap_size);
|
||||||
|
requested_heap_size += size;
|
||||||
|
return ret_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t size_needed = size - (userland_heap_size - requested_heap_size);
|
||||||
|
userland_heap_top = mmap(userland_heap_top, (uintptr_t)NULL, size_needed, false);
|
||||||
|
|
||||||
|
return mem_sbrk(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* extend_heap(size_t size)
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
size_t asize; // Adjusted size
|
||||||
|
|
||||||
|
asize = ALIGN(size);
|
||||||
|
|
||||||
|
if ((ptr = mem_sbrk(asize)) == (void*)-1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Set headers and footer
|
||||||
|
PUT_NOTAG(HDRP(ptr), PACK(asize, 0));
|
||||||
|
PUT_NOTAG(FTRP(ptr), PACK(asize, 0));
|
||||||
|
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(0, 1));
|
||||||
|
insert_node(ptr, asize);
|
||||||
|
|
||||||
|
return coalesce(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_node(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
int list = 0;
|
||||||
|
void* search_ptr = ptr;
|
||||||
|
void* insert_ptr = NULL;
|
||||||
|
|
||||||
|
// Select segregated list
|
||||||
|
while ((list < LISTLIMIT - 1) && (size > 1)) {
|
||||||
|
size >>= 1;
|
||||||
|
list++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep size ascending order and search
|
||||||
|
search_ptr = segregated_free_lists[list];
|
||||||
|
while ((search_ptr != NULL) && (size > GET_SIZE(HDRP(search_ptr)))) {
|
||||||
|
insert_ptr = search_ptr;
|
||||||
|
search_ptr = PRED(search_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set predecessor and successor
|
||||||
|
if (search_ptr != NULL) {
|
||||||
|
if (insert_ptr != NULL) {
|
||||||
|
SET_PTR(PRED_PTR(ptr), search_ptr);
|
||||||
|
SET_PTR(SUCC_PTR(search_ptr), ptr);
|
||||||
|
SET_PTR(SUCC_PTR(ptr), insert_ptr);
|
||||||
|
SET_PTR(PRED_PTR(insert_ptr), ptr);
|
||||||
|
} else {
|
||||||
|
SET_PTR(PRED_PTR(ptr), search_ptr);
|
||||||
|
SET_PTR(SUCC_PTR(search_ptr), ptr);
|
||||||
|
SET_PTR(SUCC_PTR(ptr), NULL);
|
||||||
|
segregated_free_lists[list] = ptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (insert_ptr != NULL) {
|
||||||
|
SET_PTR(PRED_PTR(ptr), NULL);
|
||||||
|
SET_PTR(SUCC_PTR(ptr), insert_ptr);
|
||||||
|
SET_PTR(PRED_PTR(insert_ptr), ptr);
|
||||||
|
} else {
|
||||||
|
SET_PTR(PRED_PTR(ptr), NULL);
|
||||||
|
SET_PTR(SUCC_PTR(ptr), NULL);
|
||||||
|
segregated_free_lists[list] = ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_node(void* ptr)
|
||||||
|
{
|
||||||
|
int list = 0;
|
||||||
|
size_t size = GET_SIZE(HDRP(ptr));
|
||||||
|
|
||||||
|
// Select segregated list
|
||||||
|
while ((list < LISTLIMIT - 1) && (size > 1)) {
|
||||||
|
size >>= 1;
|
||||||
|
list++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PRED(ptr) != NULL) {
|
||||||
|
if (SUCC(ptr) != NULL) {
|
||||||
|
SET_PTR(SUCC_PTR(PRED(ptr)), SUCC(ptr));
|
||||||
|
SET_PTR(PRED_PTR(SUCC(ptr)), PRED(ptr));
|
||||||
|
} else {
|
||||||
|
SET_PTR(SUCC_PTR(PRED(ptr)), NULL);
|
||||||
|
segregated_free_lists[list] = PRED(ptr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SUCC(ptr) != NULL) {
|
||||||
|
SET_PTR(PRED_PTR(SUCC(ptr)), NULL);
|
||||||
|
} else {
|
||||||
|
segregated_free_lists[list] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* coalesce(void* ptr)
|
||||||
|
{
|
||||||
|
size_t prev_alloc = GET_ALLOC(HDRP(PREV_BLKP(ptr)));
|
||||||
|
size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(ptr)));
|
||||||
|
size_t size = GET_SIZE(HDRP(ptr));
|
||||||
|
|
||||||
|
// Do not coalesce with previous block if the previous block is tagged with Reallocation tag
|
||||||
|
if (GET_TAG(HDRP(PREV_BLKP(ptr))))
|
||||||
|
prev_alloc = 1;
|
||||||
|
|
||||||
|
if (prev_alloc && next_alloc) { // Case 1
|
||||||
|
return ptr;
|
||||||
|
} else if (prev_alloc && !next_alloc) { // Case 2
|
||||||
|
delete_node(ptr);
|
||||||
|
delete_node(NEXT_BLKP(ptr));
|
||||||
|
size += GET_SIZE(HDRP(NEXT_BLKP(ptr)));
|
||||||
|
PUT(HDRP(ptr), PACK(size, 0));
|
||||||
|
PUT(FTRP(ptr), PACK(size, 0));
|
||||||
|
} else if (!prev_alloc && next_alloc) { // Case 3
|
||||||
|
delete_node(ptr);
|
||||||
|
delete_node(PREV_BLKP(ptr));
|
||||||
|
size += GET_SIZE(HDRP(PREV_BLKP(ptr)));
|
||||||
|
PUT(FTRP(ptr), PACK(size, 0));
|
||||||
|
PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0));
|
||||||
|
ptr = PREV_BLKP(ptr);
|
||||||
|
} else { // Case 4
|
||||||
|
delete_node(ptr);
|
||||||
|
delete_node(PREV_BLKP(ptr));
|
||||||
|
delete_node(NEXT_BLKP(ptr));
|
||||||
|
size += GET_SIZE(HDRP(PREV_BLKP(ptr))) + GET_SIZE(HDRP(NEXT_BLKP(ptr)));
|
||||||
|
PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0));
|
||||||
|
PUT(FTRP(NEXT_BLKP(ptr)), PACK(size, 0));
|
||||||
|
ptr = PREV_BLKP(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_node(ptr, size);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* place(void* ptr, size_t asize)
|
||||||
|
{
|
||||||
|
size_t ptr_size = GET_SIZE(HDRP(ptr));
|
||||||
|
size_t remainder = ptr_size - asize;
|
||||||
|
|
||||||
|
delete_node(ptr);
|
||||||
|
|
||||||
|
if (remainder <= DSIZE * 2) {
|
||||||
|
// Do not split block
|
||||||
|
PUT(HDRP(ptr), PACK(ptr_size, 1));
|
||||||
|
PUT(FTRP(ptr), PACK(ptr_size, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (asize >= 100) {
|
||||||
|
// Split block
|
||||||
|
PUT(HDRP(ptr), PACK(remainder, 0));
|
||||||
|
PUT(FTRP(ptr), PACK(remainder, 0));
|
||||||
|
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(asize, 1));
|
||||||
|
PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(asize, 1));
|
||||||
|
insert_node(ptr, remainder);
|
||||||
|
return NEXT_BLKP(ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// Split block
|
||||||
|
PUT(HDRP(ptr), PACK(asize, 1));
|
||||||
|
PUT(FTRP(ptr), PACK(asize, 1));
|
||||||
|
PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(remainder, 0));
|
||||||
|
PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(remainder, 0));
|
||||||
|
insert_node(NEXT_BLKP(ptr), remainder);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool malloc_inited = false;
|
||||||
|
int mm_init(void)
|
||||||
|
{
|
||||||
|
// init heap
|
||||||
|
userland_heap_base = task_heap_base();
|
||||||
|
userland_heap_top = userland_heap_base;
|
||||||
|
requested_heap_size = 0;
|
||||||
|
|
||||||
|
int list;
|
||||||
|
char* heap_start; // Pointer to beginning of heap
|
||||||
|
|
||||||
|
// Initialize segregated free lists
|
||||||
|
for (list = 0; list < LISTLIMIT; list++) {
|
||||||
|
segregated_free_lists[list] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the initial empty heap
|
||||||
|
if ((long)(heap_start = mem_sbrk(4 * WSIZE)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PUT_NOTAG(heap_start, 0); /* Alignment padding */
|
||||||
|
PUT_NOTAG(heap_start + (1 * WSIZE), PACK(DSIZE, 1)); /* Prologue header */
|
||||||
|
PUT_NOTAG(heap_start + (2 * WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
|
||||||
|
PUT_NOTAG(heap_start + (3 * WSIZE), PACK(0, 1)); /* Epilogue header */
|
||||||
|
|
||||||
|
if (extend_heap(INITCHUNKSIZE) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
malloc_inited = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* malloc(size_t size)
|
||||||
|
{
|
||||||
|
while (!malloc_inited) {
|
||||||
|
mm_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t asize; /* Adjusted block size */
|
||||||
|
size_t extendsize; /* Amount to extend heap if no fit */
|
||||||
|
void* ptr = NULL; /* Pointer */
|
||||||
|
|
||||||
|
// Ignore size 0 cases
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Align block size
|
||||||
|
if (size <= DSIZE) {
|
||||||
|
asize = 2 * DSIZE;
|
||||||
|
} else {
|
||||||
|
asize = ALIGN(size + DSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int list = 0;
|
||||||
|
size_t searchsize = asize;
|
||||||
|
// Search for free block in segregated list
|
||||||
|
while (list < LISTLIMIT) {
|
||||||
|
if ((list == LISTLIMIT - 1) || ((searchsize <= 1) && (segregated_free_lists[list] != NULL))) {
|
||||||
|
ptr = segregated_free_lists[list];
|
||||||
|
// Ignore blocks that are too small or marked with the reallocation bit
|
||||||
|
while ((ptr != NULL) && ((asize > GET_SIZE(HDRP(ptr))) || (GET_TAG(HDRP(ptr))))) {
|
||||||
|
ptr = PRED(ptr);
|
||||||
|
}
|
||||||
|
if (ptr != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchsize >>= 1;
|
||||||
|
list++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if free block is not found, extend the heap
|
||||||
|
if (ptr == NULL) {
|
||||||
|
extendsize = MAX(asize, CHUNKSIZE);
|
||||||
|
|
||||||
|
if ((ptr = extend_heap(extendsize)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place and divide block
|
||||||
|
ptr = place(ptr, asize);
|
||||||
|
|
||||||
|
// Return pointer to newly allocated block
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* ptr)
|
||||||
|
{
|
||||||
|
size_t size = GET_SIZE(HDRP(ptr));
|
||||||
|
|
||||||
|
REMOVE_RATAG(HDRP(NEXT_BLKP(ptr)));
|
||||||
|
PUT(HDRP(ptr), PACK(size, 0));
|
||||||
|
PUT(FTRP(ptr), PACK(size, 0));
|
||||||
|
|
||||||
|
insert_node(ptr, size);
|
||||||
|
coalesce(ptr);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @file libmalloc.h
|
* @file libmem.h
|
||||||
* @brief support malloc and free in userland
|
* @brief support malloc and free in userland
|
||||||
* @version 3.0
|
* @version 3.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
File name: libmalloc.h
|
File name: libmem.h
|
||||||
Description: support malloc and free in userland
|
Description: support malloc and free in userland
|
||||||
Others:
|
Others:
|
||||||
History:
|
History:
|
|
@ -16,9 +16,10 @@ objdump = ${toolchain}objdump
|
||||||
c_useropts = -O0
|
c_useropts = -O0
|
||||||
|
|
||||||
INC_DIR = -I$(KERNEL_ROOT)/services/app \
|
INC_DIR = -I$(KERNEL_ROOT)/services/app \
|
||||||
|
-I$(KERNEL_ROOT)/services/fs/libfs \
|
||||||
|
-I$(KERNEL_ROOT)/services/lib/memory \
|
||||||
-I$(KERNEL_ROOT)/services/lib/ipc \
|
-I$(KERNEL_ROOT)/services/lib/ipc \
|
||||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
-I$(KERNEL_ROOT)/services/boards/$(BOARD)
|
||||||
-I$(KERNEL_ROOT)/services/fs/libfs
|
|
||||||
|
|
||||||
all: shell_cmd_list.o shell_ext.o shell.o
|
all: shell_cmd_list.o shell_ext.o shell.o
|
||||||
@mv $^ ../../app
|
@mv $^ ../../app
|
||||||
|
|
|
@ -1282,7 +1282,7 @@ void shellExec(Shell* shell)
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
|
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
|
||||||
} else {
|
} else {
|
||||||
if (spawn(&session_fs, fd, read, shell->parser.param[0], shell->parser.param) < 0) {
|
if (spawn(&session_fs, fd, read, fsize, shell->parser.param[0], shell->parser.param) < 0) {
|
||||||
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
|
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
|
||||||
}
|
}
|
||||||
close(&session_fs, fd);
|
close(&session_fs, fd);
|
||||||
|
|
|
@ -74,15 +74,9 @@ typedef union {
|
||||||
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len);
|
||||||
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len);
|
||||||
|
|
||||||
struct KernReadTool {
|
|
||||||
struct Session* session;
|
|
||||||
int fd;
|
|
||||||
ipc_read_fn ipc_read;
|
|
||||||
};
|
|
||||||
|
|
||||||
int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
|
int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
|
||||||
|
|
||||||
int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv);
|
int sys_spawn(char* img_start, char* name, char** argv);
|
||||||
int sys_exit();
|
int sys_exit();
|
||||||
int sys_yield();
|
int sys_yield();
|
||||||
|
|
||||||
|
@ -91,7 +85,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session);
|
||||||
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity);
|
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity);
|
||||||
int sys_close_session(struct Session* session);
|
int sys_close_session(struct Session* session);
|
||||||
|
|
||||||
int sys_exec(struct KernReadTool* read_tool, char* name, char** argv);
|
int sys_exec(char* img_start, char* name, char** argv);
|
||||||
int sys_state(sys_state_option option, sys_state_info* info);
|
int sys_state(sys_state_option option, sys_state_info* info);
|
||||||
int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev);
|
int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ user_apps:
|
||||||
.section .rawdata_init
|
.section .rawdata_init
|
||||||
.globl initapp
|
.globl initapp
|
||||||
initapp:
|
initapp:
|
||||||
.incbin "../services/app/bin/shell"
|
.incbin "../services/app/bin/init"
|
||||||
|
|
||||||
.section .rawdata_memfs
|
.section .rawdata_memfs
|
||||||
.globl memfs
|
.globl memfs
|
||||||
|
|
|
@ -58,17 +58,17 @@ void configure_cpu(uint32_t cpu)
|
||||||
// arm_icache_enable();
|
// arm_icache_enable();
|
||||||
// arm_icache_invalidate();
|
// arm_icache_invalidate();
|
||||||
|
|
||||||
struct TraceTag main_icache_tag, main_dcache_tag;
|
// struct TraceTag main_icache_tag, main_dcache_tag;
|
||||||
AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource");
|
// AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource");
|
||||||
AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource");
|
// AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource");
|
||||||
struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag);
|
// struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag);
|
||||||
struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag);
|
// struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag);
|
||||||
// p_dcache_driver->enable();
|
// // p_dcache_driver->enable();
|
||||||
// p_dcache_driver->invalidateall();
|
// // p_dcache_driver->invalidateall();
|
||||||
// p_icache_driver->enable();
|
// // p_icache_driver->enable();
|
||||||
// p_icache_driver->invalidateall();
|
// // p_icache_driver->invalidateall();
|
||||||
p_dcache_driver->disable();
|
// p_dcache_driver->disable();
|
||||||
p_icache_driver->disable();
|
// p_icache_driver->disable();
|
||||||
|
|
||||||
// Invalidate SCU copy of TAG RAMs
|
// Invalidate SCU copy of TAG RAMs
|
||||||
scu_secure_invalidate(cpu, all_ways);
|
scu_secure_invalidate(cpu, all_ways);
|
||||||
|
@ -122,15 +122,14 @@ int main(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scu_enable();
|
scu_enable();
|
||||||
// configure_cpu(cpu_id);
|
configure_cpu(cpu_id);
|
||||||
|
|
||||||
spinlock_init(&whole_kernel_lock, "wklock");
|
spinlock_init(&whole_kernel_lock, "wklock");
|
||||||
} else {
|
} else {
|
||||||
configure_cpu(cpu_id);
|
|
||||||
spinlock_lock(&whole_kernel_lock);
|
spinlock_lock(&whole_kernel_lock);
|
||||||
|
configure_cpu(cpu_id);
|
||||||
secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag);
|
secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag);
|
||||||
DEBUG_PRINTF("CPU %d init done.\n", cur_cpuid());
|
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +161,7 @@ int main(void)
|
||||||
assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource"));
|
assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource"));
|
||||||
|
|
||||||
core_init_done |= (1 << cpu_id);
|
core_init_done |= (1 << cpu_id);
|
||||||
DEBUG("core_init_done: %x\n", core_init_done);
|
LOG_PRINTF("CPU %d init done\n", cpu_id);
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
|
|
||||||
while (core_init_done != (1 << NR_CPU) - 1)
|
while (core_init_done != (1 << NR_CPU) - 1)
|
||||||
|
|
|
@ -66,18 +66,15 @@ Modification:
|
||||||
/// @param path path to elf file
|
/// @param path path to elf file
|
||||||
/// @param argv arguments giving to main
|
/// @param argv arguments giving to main
|
||||||
/// @return
|
/// @return
|
||||||
int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv)
|
int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv)
|
||||||
{
|
{
|
||||||
|
/* load img to task */
|
||||||
|
/* 1. load elf header */
|
||||||
struct elfhdr elf;
|
struct elfhdr elf;
|
||||||
|
memcpy((void*)&elf, img_start, sizeof(elf));
|
||||||
|
// pgdir for new task
|
||||||
struct TopLevelPageDirectory pgdir;
|
struct TopLevelPageDirectory pgdir;
|
||||||
pgdir.pd_addr = NULL;
|
pgdir.pd_addr = NULL;
|
||||||
|
|
||||||
if (ipc_read(session, fd, (char*)&elf, 0, sizeof(elf)) < sizeof(elf) || elf.magic != ELF_MAGIC) {
|
|
||||||
ERROR("invalide elf file.\n");
|
|
||||||
goto error_exec;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pgdir for new task
|
|
||||||
if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) {
|
if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) {
|
||||||
ERROR("create new pgdir failed.\n");
|
ERROR("create new pgdir failed.\n");
|
||||||
goto error_exec;
|
goto error_exec;
|
||||||
|
@ -88,10 +85,8 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
|
||||||
uintptr_t load_size = 0;
|
uintptr_t load_size = 0;
|
||||||
struct proghdr ph;
|
struct proghdr ph;
|
||||||
for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) {
|
for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) {
|
||||||
if (ipc_read(session, fd, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) {
|
// load proghdr
|
||||||
ERROR("Read elf header failed\n");
|
memcpy((char*)&ph, img_start + off, sizeof(ph));
|
||||||
goto error_exec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ph.type != ELF_PROG_LOAD)
|
if (ph.type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
@ -114,10 +109,7 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
|
||||||
panic("copy elf file to unmapped addr");
|
panic("copy elf file to unmapped addr");
|
||||||
}
|
}
|
||||||
uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE);
|
uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE);
|
||||||
if (read_size != ipc_read(session, fd, P2V(page_paddr), ph.off + addr_offset, read_size)) {
|
memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size);
|
||||||
ERROR("read size error, off: %d, read len: %d\n", ph.off + addr_offset, read_size);
|
|
||||||
goto error_exec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +185,7 @@ error_exec:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_exec(struct KernReadTool* read_tool, char* name, char** argv)
|
int sys_exec(char* img_start, char* name, char** argv)
|
||||||
{
|
{
|
||||||
/// @todo find a source of mmu_driver_tag instead of requiring from root
|
/// @todo find a source of mmu_driver_tag instead of requiring from root
|
||||||
static struct TraceTag mmu_driver_tag;
|
static struct TraceTag mmu_driver_tag;
|
||||||
|
@ -204,12 +196,8 @@ int sys_exec(struct KernReadTool* read_tool, char* name, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag);
|
struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag);
|
||||||
|
|
||||||
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
|
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
|
||||||
struct Session* session = read_tool->session;
|
int ret = task_exec(current_task, img_start, name, argv);
|
||||||
int fd = read_tool->fd;
|
|
||||||
ipc_read_fn ipc_read = read_tool->ipc_read;
|
|
||||||
int ret = task_exec(current_task, session, fd, ipc_read, name, argv);
|
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
spinlock_init(¤t_task->lock, current_task->name);
|
spinlock_init(¤t_task->lock, current_task->name);
|
||||||
p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr));
|
p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr));
|
||||||
|
|
|
@ -33,8 +33,8 @@ Modification:
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
extern int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv);
|
extern int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv);
|
||||||
int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv)
|
int sys_spawn(char* img_start, char* name, char** argv)
|
||||||
{
|
{
|
||||||
// alloc a new pcb
|
// alloc a new pcb
|
||||||
struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb();
|
struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb();
|
||||||
|
@ -44,11 +44,7 @@ int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv)
|
||||||
}
|
}
|
||||||
// init trapframe
|
// init trapframe
|
||||||
arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0);
|
arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0);
|
||||||
|
if (UNLIKELY(task_exec(new_task_cb, img_start, name, argv)) < 0) {
|
||||||
struct Session* session = read_tool->session;
|
|
||||||
int fd = read_tool->fd;
|
|
||||||
ipc_read_fn ipc_read = read_tool->ipc_read;
|
|
||||||
if (UNLIKELY(task_exec(new_task_cb, session, fd, ipc_read, name, argv)) < 0) {
|
|
||||||
xizi_task_manager.free_pcb(new_task_cb);
|
xizi_task_manager.free_pcb(new_task_cb);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,17 @@ static inline void _padding(char* name)
|
||||||
void show_tasks(void)
|
void show_tasks(void)
|
||||||
{
|
{
|
||||||
struct TaskMicroDescriptor* task = NULL;
|
struct TaskMicroDescriptor* task = NULL;
|
||||||
DEBUG_PRINTF("******************************************************\n");
|
LOG_PRINTF("******************************************************\n");
|
||||||
DEBUG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n");
|
for (int i = 0; i < NR_CPU; i++) {
|
||||||
|
LOG_PRINTF("CPU %d: ", i);
|
||||||
|
if (global_cpus[i].task != NULL) {
|
||||||
|
LOG_PRINTF("%s\n", global_cpus[i].task->name);
|
||||||
|
} else {
|
||||||
|
LOG_PRINTF("NULL\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_PRINTF("******************************************************\n");
|
||||||
|
LOG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n");
|
||||||
for (int i = 0; i < TASK_MAX_PRIORITY; i++) {
|
for (int i = 0; i < TASK_MAX_PRIORITY; i++) {
|
||||||
if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) {
|
if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -64,19 +73,19 @@ void show_tasks(void)
|
||||||
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
|
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
|
||||||
{
|
{
|
||||||
if (task->state == INIT)
|
if (task->state == INIT)
|
||||||
DEBUG_PRINTF(" INIT ");
|
LOG_PRINTF(" INIT ");
|
||||||
else if (task->state == READY)
|
else if (task->state == READY)
|
||||||
DEBUG_PRINTF(" READY ");
|
LOG_PRINTF(" READY ");
|
||||||
else if (task->state == RUNNING)
|
else if (task->state == RUNNING)
|
||||||
DEBUG_PRINTF("RUNNING ");
|
LOG_PRINTF("RUNNING ");
|
||||||
else if (task->state == DEAD)
|
else if (task->state == DEAD)
|
||||||
DEBUG_PRINTF(" DEAD ");
|
LOG_PRINTF(" DEAD ");
|
||||||
|
|
||||||
_padding(task->name);
|
_padding(task->name);
|
||||||
DEBUG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick);
|
LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_PRINTF("******************************************************\n");
|
LOG_PRINTF("******************************************************\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +94,8 @@ extern struct KBuddy kern_virtmem_buddy;
|
||||||
extern uint32_t kernel_data_end[];
|
extern uint32_t kernel_data_end[];
|
||||||
void show_mem(void)
|
void show_mem(void)
|
||||||
{
|
{
|
||||||
DEBUG_PRINTF("*********************************************************\n");
|
LOG_PRINTF("*********************************************************\n");
|
||||||
DEBUG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n");
|
LOG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n");
|
||||||
|
|
||||||
uint32_t total = (PHY_MEM_STOP - V2P(kernel_data_end)) >> 10;
|
uint32_t total = (PHY_MEM_STOP - V2P(kernel_data_end)) >> 10;
|
||||||
uint32_t used = 0;
|
uint32_t used = 0;
|
||||||
|
@ -96,14 +105,14 @@ void show_mem(void)
|
||||||
}
|
}
|
||||||
used = used >> 10;
|
used = used >> 10;
|
||||||
|
|
||||||
DEBUG_PRINTF(" %d %d %d\n", total, total - used, used);
|
LOG_PRINTF(" %d %d %d\n", total, total - used, used);
|
||||||
DEBUG_PRINTF("*********************************************************\n");
|
LOG_PRINTF("*********************************************************\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_cpu(void)
|
void show_cpu(void)
|
||||||
{
|
{
|
||||||
DEBUG_PRINTF("**********************************************************\n");
|
LOG_PRINTF("**********************************************************\n");
|
||||||
#ifdef ARCH_SMP
|
#ifdef ARCH_SMP
|
||||||
/// @todo support smp
|
/// @todo support smp
|
||||||
KPrintf(" cpu VALUE \n");
|
KPrintf(" cpu VALUE \n");
|
||||||
|
@ -116,10 +125,10 @@ void show_cpu(void)
|
||||||
|
|
||||||
_padding(current_task->name);
|
_padding(current_task->name);
|
||||||
|
|
||||||
DEBUG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n");
|
LOG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n");
|
||||||
DEBUG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick);
|
LOG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick);
|
||||||
|
|
||||||
DEBUG_PRINTF("***********************************************************\n");
|
LOG_PRINTF("***********************************************************\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case SYSCALL_SPAWN:
|
case SYSCALL_SPAWN:
|
||||||
ret = sys_spawn((struct KernReadTool*)param1, (char*)param2, (char**)param3);
|
ret = sys_spawn((char*)param1, (char*)param2, (char**)param3);
|
||||||
break;
|
break;
|
||||||
case SYSCALL_EXIT:
|
case SYSCALL_EXIT:
|
||||||
ret = sys_exit();
|
ret = sys_exit();
|
||||||
|
@ -62,7 +62,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
|
||||||
ret = sys_close_session((struct Session*)param1);
|
ret = sys_close_session((struct Session*)param1);
|
||||||
break;
|
break;
|
||||||
case SYSCALL_EXEC:
|
case SYSCALL_EXEC:
|
||||||
ret = sys_exec((struct KernReadTool*)param1, (char*)param2, (char**)param3);
|
ret = sys_exec((char*)param1, (char*)param2, (char**)param3);
|
||||||
break;
|
break;
|
||||||
case SYSCALL_SYS_STATE:
|
case SYSCALL_SYS_STATE:
|
||||||
ret = sys_state(param1, (sys_state_info*)param2);
|
ret = sys_state(param1, (sys_state_info*)param2);
|
||||||
|
|
|
@ -181,34 +181,29 @@ static void _scheduler(struct SchedulerRightGroup right_group)
|
||||||
|
|
||||||
spinlock_lock(&whole_kernel_lock);
|
spinlock_lock(&whole_kernel_lock);
|
||||||
while (1) {
|
while (1) {
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
|
||||||
spinlock_lock(&xizi_task_manager.lock);
|
|
||||||
next_task = NULL;
|
next_task = NULL;
|
||||||
/* find next runnable task */
|
/* find next runnable task */
|
||||||
assert(cur_cpu()->task == NULL);
|
assert(cur_cpu()->task == NULL);
|
||||||
if (next_task_emergency != NULL) {
|
if (next_task_emergency != NULL) {
|
||||||
next_task = next_task_emergency;
|
next_task = next_task_emergency;
|
||||||
spinlock_lock(&next_task->lock);
|
|
||||||
next_task->state = RUNNING;
|
next_task->state = RUNNING;
|
||||||
spinlock_unlock(&next_task->lock);
|
|
||||||
next_task_emergency = NULL;
|
next_task_emergency = NULL;
|
||||||
} else {
|
} else {
|
||||||
next_task = xizi_task_manager.next_runnable_task();
|
next_task = xizi_task_manager.next_runnable_task();
|
||||||
}
|
}
|
||||||
spinlock_unlock(&xizi_task_manager.lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
|
|
||||||
/* not a runnable task */
|
/* not a runnable task */
|
||||||
if (UNLIKELY(next_task == NULL)) {
|
if (UNLIKELY(next_task == NULL) || UNLIKELY(next_task->state != RUNNING)) {
|
||||||
|
spinlock_lock(&whole_kernel_lock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* a runnable task */
|
||||||
spinlock_lock(&whole_kernel_lock);
|
spinlock_lock(&whole_kernel_lock);
|
||||||
assert(next_task->state == RUNNING);
|
|
||||||
// p_mmu_driver->LoadPgdirCrit((uintptr_t)V2P(next_task->pgdir.pd_addr), &right_group.intr_driver_tag);
|
|
||||||
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
|
|
||||||
|
|
||||||
struct CPU* cpu = cur_cpu();
|
struct CPU* cpu = cur_cpu();
|
||||||
cpu->task = next_task;
|
cpu->task = next_task;
|
||||||
// DEBUG_PRINTF("CPU %d switch to task %s\n", cur_cpuid(), next_task->name);
|
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
|
||||||
context_switch(&cpu->scheduler, next_task->main_thread.context);
|
context_switch(&cpu->scheduler, next_task->main_thread.context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ void intr_irq_dispatch(struct trapframe* tf)
|
||||||
if ((int_info = p_intr_driver->hw_before_irq()) == 0) {
|
if ((int_info = p_intr_driver->hw_before_irq()) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// spinlock_lock(&whole_kernel_lock);
|
spinlock_lock(&whole_kernel_lock);
|
||||||
DSB();
|
DSB();
|
||||||
// DEBUG("CPU %d in\n", cur_cpuid());
|
// DEBUG("CPU %d in\n", cur_cpuid());
|
||||||
|
|
||||||
|
@ -96,6 +96,6 @@ void intr_irq_dispatch(struct trapframe* tf)
|
||||||
assert(current_task == cur_cpu()->task);
|
assert(current_task == cur_cpu()->task);
|
||||||
|
|
||||||
// DEBUG("CPU %d out\n", cur_cpuid());
|
// DEBUG("CPU %d out\n", cur_cpuid());
|
||||||
// spinlock_unlock(&whole_kernel_lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
p_intr_driver->cpu_irq_enable();
|
p_intr_driver->cpu_irq_enable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ void software_irq_dispatch(struct trapframe* tf)
|
||||||
assert(p_intr_driver != NULL);
|
assert(p_intr_driver != NULL);
|
||||||
|
|
||||||
p_intr_driver->cpu_irq_disable();
|
p_intr_driver->cpu_irq_disable();
|
||||||
// spinlock_lock(&whole_kernel_lock);
|
spinlock_lock(&whole_kernel_lock);
|
||||||
DSB();
|
DSB();
|
||||||
// DEBUG("CPU %d in\n", cur_cpuid());
|
// DEBUG("CPU %d in\n", cur_cpuid());
|
||||||
// get current task
|
// get current task
|
||||||
|
@ -78,10 +78,10 @@ void software_irq_dispatch(struct trapframe* tf)
|
||||||
}
|
}
|
||||||
assert(cur_task == cur_cpu()->task);
|
assert(cur_task == cur_cpu()->task);
|
||||||
if (syscall_num == SYSCALL_EXIT) {
|
if (syscall_num == SYSCALL_EXIT) {
|
||||||
ERROR("Exit reaches");
|
panic("Exit reaches");
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG("CPU %d out\n", cur_cpuid());
|
// DEBUG("CPU %d out\n", cur_cpuid());
|
||||||
// spinlock_unlock(&whole_kernel_lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
p_intr_driver->cpu_irq_enable();
|
p_intr_driver->cpu_irq_enable();
|
||||||
}
|
}
|
Loading…
Reference in New Issue