├── .gitignore ├── README.md └── lab4 ├── Makefile ├── gdb ├── kernel ├── arm │ ├── arm_i.h │ ├── asm_irq_handler.S │ ├── asm_swi_handler.S │ ├── enter_user_mode.S │ ├── handler.c │ ├── interrupt.c │ ├── kernel.mk │ ├── psr.c │ ├── reg.c │ ├── swi.c │ └── timer.c ├── assert.c ├── ctype.c ├── device.c ├── hexdump.c ├── include │ ├── arm │ │ ├── exception.h │ │ ├── interrupt.h │ │ ├── physmem.h │ │ ├── psr.h │ │ ├── reg.h │ │ ├── swi.h │ │ └── timer.h │ ├── asm.h │ ├── assert.h │ ├── bits │ │ ├── errno.h │ │ ├── fileno.h │ │ └── swi.h │ ├── config.h │ ├── ctype.h │ ├── device.h │ ├── inline.h │ ├── kernel.h │ ├── lock.h │ ├── math.h │ ├── sched.h │ ├── stdarg.h │ ├── syscall.h │ ├── task.h │ └── types.h ├── kernel.mk ├── lock │ ├── kernel.mk │ └── mutex.c ├── main.c ├── math.c ├── memcheck.c ├── raise.c ├── sched │ ├── ctx_switch.c │ ├── ctx_switch_asm.S │ ├── kernel.mk │ ├── run_queue.c │ ├── sched.c │ ├── sched_i.h │ └── ub_test.c ├── start.S └── syscall │ ├── io.c │ ├── kernel.mk │ ├── proc.c │ └── time.c ├── mount.sh ├── tasks ├── cyclone │ ├── cyclone.c │ └── pack.mk ├── dagger │ ├── dagger.c │ ├── dagger.dep │ └── pack.mk ├── hello │ ├── hello.c │ └── pack.mk ├── libc │ ├── crt0.S │ ├── include │ │ ├── asm.h │ │ ├── bits │ │ │ ├── dev.h │ │ │ ├── errno.h │ │ │ ├── fileno.h │ │ │ ├── swi.h │ │ │ └── types.h │ │ ├── ctype.h │ │ ├── errno.h │ │ ├── inline.h │ │ ├── lock.h │ │ ├── stdarg.h │ │ ├── stdio.h │ │ ├── stdlib.h │ │ ├── string.h │ │ ├── sys │ │ │ └── types.h │ │ ├── task.h │ │ └── unistd.h │ ├── libc.mk │ ├── raise.c │ ├── stdio │ │ ├── doprnt.c │ │ ├── doprnt.h │ │ ├── doscan.c │ │ ├── doscan.h │ │ ├── hexdump.c │ │ ├── libc.mk │ │ ├── printf.c │ │ ├── putchar.c │ │ ├── puts.c │ │ ├── sprintf.c │ │ └── sscanf.c │ ├── stdlib │ │ ├── atoi.c │ │ ├── ctype.c │ │ ├── errno.c │ │ ├── libc.mk │ │ ├── rand.c │ │ ├── strtol.c │ │ └── strtoul.c │ ├── string │ │ ├── libc.mk │ │ ├── memcmp.c │ │ ├── memmove.c │ │ ├── memset.c │ │ ├── strcat.c │ │ ├── strchr.c │ │ ├── strcmp.c │ │ ├── strcpy.c │ │ ├── strcspn.c │ │ ├── strlen.c │ │ ├── strncat.c │ │ ├── strncmp.c │ │ ├── strncpy.c │ │ ├── strpbrk.c │ │ ├── strrchr.c │ │ ├── strspn.c │ │ └── strstr.c │ └── swi │ │ ├── event_wait.S │ │ ├── libc.mk │ │ ├── mutex_create.S │ │ ├── mutex_lock.S │ │ ├── mutex_unlock.S │ │ ├── read.S │ │ ├── sleep.S │ │ ├── task_create.S │ │ ├── time.S │ │ └── write.S ├── mutex_chaser │ ├── mutex_chaser.c │ └── pack.mk ├── simple_mutex │ ├── pack.mk │ ├── simple_mutex.c │ └── simple_mutex.dep ├── skyeye.conf ├── stress │ ├── .stress.c.swp │ ├── pack.mk │ └── stress.c ├── sys_err │ ├── pack.mk │ └── sys_err.c └── tasks.mk └── uboot ├── include ├── _exports.h └── exports.h ├── stubs.c └── uboot.mk /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Real-Time Operating Systems 2 | Implemented the internals of a real-time operating system. Real time operating systems have a number of subsystems, but their most important functions are task scheduling, resource allocation and memory protection (a form of fault isolation). 3 | 4 | We implemented the basic infrastructure, context switching, task management, concurrency control through mutexes and interface layers with admission control and the priority inheritance locking discipline. 5 | 6 | 7 | Scheduler: 8 | The scheduler is a part of the kernel that is in charge of deciding the order in which tasks run and the length of each run. The scheduling policy that a scheduler follows is the theoretical frame- work that the scheduler employs in making its allocation decisions. Note that there is no mention of context switching or architecture specific implementation details. In this lab, you will be implement- ing sections of a scheduler, and in particular the predicates needed to implement the rate monotonic scheduling policy. 9 | 10 | Dispatcher: 11 | The dispatcher deals with enforcing the scheduler’s policy. The context switch and task switch routines are under the purview of the dispatcher. 12 | 13 | Run queue: 14 | The run queue or run list is a list of tasks that are currently runnable that satisfy some criteria. On simple round-robin scheduling systems, there is one system run list where runnable tasks are served in a first come first served (FCFS) manner (hence the name run queue). Systems that have multiple task priorities do not have a universal run queue. Gravelv2 has a ‘run list’ for every priority level on the system, but since there are as many priorities as tasks on Gravelv2, the scheduler enforces that no more than one task can be in a run queue at once. Hence, we end up not using the FCFS nature of the queue, working instead on a purely priority based scheduling policy. 15 | 16 | Task state: 17 | During the life-time of a task, it can be in a number of states. All tasks start out as runnable. The scheduler can only schedule runnable tasks to run. When a runnable task is scheduled to run, it is now in the running state. A running task can block on a lock or an event. When it does this, the task moves to the blocked state. A task that is blocked cannot be scheduled to run. It can be made runnable upon the signaling of an appropriate event. In traditional operating systems, a task that is exiting will move from the running state to the undead or zombie state at which point it will be reaped and have its resources returned to the system in an appropriate manner. In Gravelv2, no tasks exit and all tasks are assumed to be periodic forever. Please remember that the scheduler will not (and is not supposed to) schedule any task that is not runnable. 18 | -------------------------------------------------------------------------------- /lab4/Makefile: -------------------------------------------------------------------------------- 1 | # Root 18-349 Makefile 2 | # Borrowed from 15410 Makefile -- thanks nwf and co. 3 | # 4 | 5 | # Change this to blank if you are on the gumstix 6 | #CCPREFIX = arm-softfloat-linux-gnu- 7 | CCPREFIX = arm-linux- 8 | 9 | MAKEFLAGS += -rR 10 | 11 | ############### RULE HEADER ##################### 12 | 13 | # The packages are all phony targets. They produce files in the bin directory. 14 | # Make sure there are no name clashes. Add new ones here if you make your own 15 | # tests (which I recommend you do). 16 | 17 | PACKAGES = dagger hello cyclone mutex_chaser simple_mutex stress sys_err 18 | 19 | .PHONY: all package clean clobber $(PACKAGES) 20 | all: package kernel 21 | 22 | 23 | ############### ENVIRONMENT ##################### 24 | 25 | CC = $(CCPREFIX)gcc 26 | LD = $(CCPREFIX)ld 27 | AR = $(CCPREFIX)ar 28 | OBJCOPY = $(CCPREFIX)objcopy 29 | RM = rm -f 30 | 31 | ROOT = $(PWD) 32 | KDIR = $(ROOT)/kernel 33 | UDIR = $(ROOT)/uboot 34 | TDIR = $(ROOT)/tasks 35 | TLIBCDIR = $(TDIR)/libc 36 | 37 | LIBGCC = `$(CC) -print-libgcc-file-name` 38 | 39 | ############## CONFIGURATION #################### 40 | 41 | # Entry point addresses 42 | KLOAD_ADDR = 0xa3000000 43 | TLOAD_ADDR = 0xa0000000 44 | 45 | # These are extra warning that you may find helpful. These may give spurious 46 | # warnings but are good for debugging code. 47 | CWARNINGS_NOISY = -Wformat=2 -Wstrict-aliasing=2 -Wshadow -Wcast-qual \ 48 | -Wstrict-prototypes -Wold-style-definition 49 | CWARNINGS_SAFE = -Wall -Wno-unused-parameter -Wextra -Wpointer-arith \ 50 | -Wwrite-strings -Wsystem-headers 51 | 52 | CWARNINGS = $(CWARNINGS_SAFE) 53 | CWARNINGS1 = $(CWARNINGS_SAFE) $(CWARNINGS_NOISY) 54 | 55 | KCFLAGS = -Os -ffreestanding -ffixed-r8 -nostdinc $(CWARNINGS) -g 56 | TCFLAGS = -Os -ffreestanding -nostdinc $(CWARNINGS) -g 57 | ASFLAGS = -nostdinc -Wall -Wextra -Werror -DASSEMBLER 58 | KLDFLAGS = -nostdlib -N --fatal-warnings --warn-common -Ttext $(KLOAD_ADDR) 59 | TLDFLAGS = -nostdlib -N --fatal-warnings --warn-common -Ttext $(TLOAD_ADDR) 60 | 61 | KINCLUDES = -I$(UDIR)/include -I$(KDIR)/include 62 | TINCLUDES = -I$(TLIBCDIR)/include 63 | 64 | ########### SUBFOLDER INCLUDES ################## 65 | 66 | include $(UDIR)/uboot.mk 67 | include $(KDIR)/kernel.mk 68 | include $(TDIR)/tasks.mk 69 | 70 | 71 | ########### PATTERNED VARIABLES ################# 72 | 73 | $(TDIR)/%: INCLUDES=$(TINCLUDES) 74 | $(KDIR)/%: INCLUDES=$(KINCLUDES) 75 | $(UDIR)/%: INCLUDES=$(KINCLUDES) 76 | 77 | $(TDIR)/%: CFLAGS=$(TCFLAGS) 78 | $(KDIR)/%: CFLAGS=$(KCFLAGS) 79 | $(UDIR)/%: CFLAGS=$(KCFLAGS) 80 | 81 | $(TDIR)/%: LDFLAGS=$(TLDFLAGS) 82 | $(KDIR)/%: LDFLAGS=$(KLDFLAGS) 83 | $(UDIR)/%: LDFLAGS=$(KLDFLAGS) 84 | 85 | 86 | ############### PACKAGE RULES ################### 87 | 88 | package: $(PACKAGES) 89 | kernel : $(KERNEL).bin 90 | 91 | ############### GENERIC RULES ################### 92 | 93 | %.dep: %.S 94 | @echo DEP $(notdir $<) 95 | @$(CC) $(ASFLAGS) -DASSEMBLER $(INCLUDES) -M -MP -MF $@ -MT $(<:.S=.o) $< 96 | 97 | %.dep: %.s 98 | @echo "You should use the .S file extension rather than .s" 99 | @echo ".s does not support precompiler directives (like #include)" 100 | @false 101 | 102 | %.dep: %.c 103 | @echo DEP $(notdir $<) 104 | @$(CC) $(CFLAGS) $(INCLUDES) -M -MP -MF $@ -MT $(<:.c=.o) $< 105 | 106 | %.o: %.S 107 | @echo CC $(notdir $<) 108 | @$(CC) $(ASFLAGS) $(INCLUDES) -c -o $@ $< 109 | 110 | %.o: %.s 111 | @echo "You should use the .S file extension rather than .s" 112 | @echo ".s does not support precompiler directives (like #include)" 113 | @false 114 | 115 | %.o: %.c 116 | @echo CC $(notdir $<) 117 | @$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< 118 | 119 | %.a: 120 | @echo AR $(notdir $@) 121 | @$(AR) rcs $@ $^ 122 | 123 | %.bin: % 124 | @echo OBJCOPY $(notdir $<) $(notdir $@) 125 | @$(OBJCOPY) -O binary $< $@ 126 | 127 | 128 | ############### CLEANING RULES ################## 129 | 130 | clean: 131 | @echo CLEAN objects 132 | @$(RM) $(ALL_OBJS) 133 | @echo CLEAN deps 134 | @$(RM) $(ALL_OBJS:%.o=%.dep) 135 | @echo CLEAN archives/misc 136 | @$(RM) $(ALL_CLEANS) 137 | 138 | clobber: clean 139 | @echo CLEAN packages 140 | @$(RM) $(PACKAGE_TARGETS) 141 | @echo CLEAN package bins 142 | @$(RM) $(PACKAGE_TARGETS:%=%.bin) 143 | @echo CLEAN others 144 | @$(RM) $(ALL_CLOBBERS) 145 | 146 | 147 | ########### DEPENDENCY FILE INCLUSION ############ 148 | 149 | ifeq (0,$(words $(findstring clean,$(MAKECMDGOALS)))) 150 | ifeq (0,$(words $(findstring clobber,$(MAKECMDGOALS)))) 151 | ifneq (,$(ALL_OBJS)) 152 | -include $(ALL_OBJS:.o=.dep) 153 | endif 154 | endif 155 | endif 156 | 157 | -------------------------------------------------------------------------------- /lab4/gdb: -------------------------------------------------------------------------------- 1 | ./copy2sd.sh ~/342_embeded/lab4/kernel/kernel.bin ~/342_embeded/lab4/tasks/bin/hello.bin 2 | 3 | gdb-multiarch 4 | set architecture armv5te 5 | target remote localhost:1234 6 | 7 | add-symbol-file ~/342_embeded/lab4/kernel/kernel 0xa3000000 8 | add-symbol-file ~/342_embeded/lab4/tasks/bin/hello 0xa0000000 9 | 10 | fatload mmc 0 0xa3000000 kernel.bin 11 | fatload mmc 0 0xa0000000 hello.bin 12 | 13 | -------------------------------------------------------------------------------- /lab4/kernel/arm/arm_i.h: -------------------------------------------------------------------------------- 1 | /** @file arm_i.h 2 | * 3 | * @brief Internal header -- install and restore handler routines. 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * Date: 2014-11-24 8 | */ 9 | 10 | #ifndef _ARM_I_H_ 11 | #define _ARM_I_H_ 12 | 13 | unsigned install_handler(uint32_t vec_address, uint32_t *new_address, uint32_t **handler_location, 14 | uint32_t *instruction1, uint32_t *instruction2); 15 | 16 | void restore_handler(uint32_t *handler_location, uint32_t instruction1, uint32_t instruction2); 17 | 18 | #endif /* _ARM_I_H_ */ 19 | -------------------------------------------------------------------------------- /lab4/kernel/arm/asm_irq_handler.S: -------------------------------------------------------------------------------- 1 | /** @file asm_irq_handle.S 2 | * 3 | * @brief Assembly assistance functions to handle interrupts. 4 | * 5 | * We handle interrupts in SVC mode with interrupts disabled. Hence we perform 6 | * this elaborate waltz to transplant ourselves onto the svc stack, regardless 7 | * of the source of the IRQ. 8 | * 9 | *@ Author: Huacong Cai 10 | * Qinyu Tong 11 | * 12 | *@ Date: Sun, 19 Oct 2014 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | .file "asm_irq_handler.S" 19 | 20 | .extern c_irq_handler 21 | 22 | /* 23 | * Code to take an IRQ. 24 | */ 25 | FUNC(irq_handler) 26 | /* lr starts off pointing at next instruction + 4 -- fix this. */ 27 | sub lr, lr, #4 28 | 29 | /* No nesting -- this is a temporary stack. */ 30 | ldr sp, =irq_stack_hi 31 | stmfd sp!, {r0,r1} 32 | 33 | /* Move special regs into r0, r1. */ 34 | mrs r0, spsr 35 | mov r1, lr 36 | 37 | /* Switch to supervisor mode */ 38 | msr cpsr_c, #(PSR_MODE_SVC | PSR_IRQ) 39 | 40 | /* Diq the spsr_svc because svc-mode (SWI) entry code saves it with IRQ 41 | * disabled. I feel so dirty doing this. 42 | * We need to diq spsr because we need atomic reload of pc and cpsr 43 | * during the return sequence in case we came in from user mode. 44 | */ 45 | msr spsr, r0 46 | 47 | /* Save lr, pop of r0, r1 from irq stack, and then put them all on the 48 | * svc stack along with other caller-save registers. 49 | * The stack will look like: 50 | * {r0-r3, r8, ip, lr, pc} of source 51 | */ 52 | stmfd sp!, {r1} 53 | ldr r1, =irq_stack_lo 54 | ldm r1, {r0, r1} 55 | stmfd sp!, {r0-r3, r8, ip, lr} 56 | 57 | /* Recover user registers and save */ 58 | mrs r0, spsr 59 | stmfd sp, {r0, sp, lr}^ 60 | add sp, sp, #-12 61 | 62 | /* Set up r8 correctly with u-boot dispatch table. */ 63 | ldr ip, =global_data 64 | ldr r8, [ip] 65 | 66 | /* Call the IRQ handler in C. */ 67 | bl c_irq_handler 68 | @mov r0, sp 69 | @mov r1, #128 70 | @bl hexdump 71 | 72 | /* Restore registers. Also restore CPSR. */ 73 | ldmfd sp, {r0, sp, lr}^ 74 | add sp, sp, #12 75 | msr spsr, r0 76 | ldmfd sp!, {r0-r3, r8, ip, lr, pc}^ 77 | 78 | /* 79 | * We have exactly one IRQ save area. This is shared across all tasks. When an 80 | * IRQ is taken, this region is used as a temporary area to shuffle values across 81 | * the the SVC stack. We don't want a full block IRQ stack, let alone an IRQ stack 82 | * per task. 83 | */ 84 | .bss 85 | ALIGN8 86 | GLOBAL(irq_stack_lo) 87 | .space 8 88 | GLOBAL(irq_stack_hi) 89 | 90 | -------------------------------------------------------------------------------- /lab4/kernel/arm/asm_swi_handler.S: -------------------------------------------------------------------------------- 1 | /* @ swi_handler.S: SWI handler routine 2 | * 3 | * it first store registers and spsr and enable irq. 4 | * Then call c_swi_handler. After c_swi_handler returns, restores registers and spsr. 5 | * 6 | * @ Author: Huacong Cai 7 | * Qinyu Tong 8 | * 9 | * Date: 2014-11-24 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | .file "swi_handler.S" 16 | 17 | .extern global_data 18 | .extern swi_dispatch 19 | 20 | FUNC(swi_handler) 21 | sub sp, sp, #4 @leave room on stack for SPSR 22 | stmfd sp!, {r0-r12, lr} @store user's gpregisters 23 | 24 | mrs r2, spsr @get SPSR into gpregisters 25 | str r2, [sp, #14*4] @store SPSR above gpregisters 26 | 27 | stmfd sp, {sp, lr}^ 28 | add sp, sp, #-8 29 | 30 | @enable irq as soon as possible 31 | mrs r2, cpsr 32 | bic r2, r2, #PSR_IRQ 33 | msr cpsr, r2 34 | 35 | add r1, sp, #8 @pointer to parameters on stack 36 | ldr r0, [lr, #-4] @extract the SWI number 37 | bic r0, r0, #0xff000000 @get SWI # by bit-masking 38 | 39 | @restore r8 40 | ldr r2, =global_data 41 | ldr r8, [r2] 42 | 43 | bl swi_dispatch @goto handler 44 | 45 | ldmfd sp, {sp, lr}^ 46 | add sp, sp, #8 47 | 48 | ldr r2, [sp, #14*4] @restore SPSR 49 | msr spsr, r2 @restore SPSR from r2 50 | ldmfd sp!, {r0-r12, lr} @unstackuser's registers 51 | add sp, sp, #4 @remove space used to store SPSR 52 | 53 | movs pc, lr @return from handler 54 | -------------------------------------------------------------------------------- /lab4/kernel/arm/enter_user_mode.S: -------------------------------------------------------------------------------- 1 | /* 2 | * @ init_user_mode.S: User mode initialize routine 3 | * 4 | * @ Author: Huacong Cai 5 | * Qinyu Tong 6 | * @ Date: 2014-11-24 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define SWI_BASE 0x900000 15 | #define EXIT_SWI (SWI_BASE + 1) 16 | 17 | .file "enter_user_mode.S" 18 | 19 | .extern old_sp 20 | 21 | FUNC(enter_user_mode) 22 | @save state 23 | stmfd sp!, {r1-r12, lr} @store r1 to r12 and lr 24 | 25 | @save sp 26 | ldr r2, =old_sp 27 | str sp, [r2] @save kernal's sp 28 | 29 | @set cpsr 30 | mrs r2, cpsr @load cpsr 31 | 32 | @clear i and mode 33 | bic r2, r2, #PSR_MODE 34 | bic r2, r2, #PSR_IRQ 35 | 36 | @set iFt_USER 37 | orr r2, r2, #PSR_MODE_USR 38 | orr r2, r2, #PSR_FIQ 39 | 40 | msr cpsr, r2 41 | 42 | @set user stack 43 | ldr sp, =USR_STACK @set the bottom of user stack 44 | 45 | @loop for copying argv[i] 46 | mov r2, r0 47 | add r1, r1, r0, LSL #2 48 | 49 | LC1: 50 | sub r1, r1, #4 @push all addresses of strings reference by argv into stack 51 | ldr r3, [r1] 52 | str r3, [sp, #-4]! 53 | 54 | sub r2, r2, #1 55 | cmp r2, #0 56 | bgt LC1 57 | 58 | str r0, [sp, #-4]! @push argc into stack 59 | 60 | @jump to user program 61 | ldr r2, =USR_START_ADDR 62 | blx r2 @jump to user program 63 | 64 | swi EXIT_SWI 65 | 66 | -------------------------------------------------------------------------------- /lab4/kernel/arm/handler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * handler.c: install and restore handler routines 3 | * 4 | * Author: Huacong Cai 5 | * Qingyu Tong 6 | * Date: 2014-11-08 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #define LDR_OFFSET 0x00000FFF 13 | #define LDR_INSTRCTION 0xFFFFF000 14 | #define LDR_UBIT 0x00800000 15 | 16 | #define LDR_PC_PLUS 0xE59FF000 17 | #define LDR_PC_MINUS 0xE51FF000 18 | #define LDR_PC_MINUS_FOUR 0xE51FF004 19 | 20 | /* 21 | * ret 0 success 22 | * 0x0badc0de instruction in vec_address is unrecognized 23 | */ 24 | unsigned install_handler(uint32_t vec_address, uint32_t *new_address, uint32_t **handler_location, 25 | uint32_t *instruction1, uint32_t *instruction2) 26 | { 27 | uint32_t vec_instruction; 28 | uint32_t offset; 29 | uint32_t instruction; 30 | uint32_t *jumptable; 31 | 32 | //verify if given vec_address is valid 33 | vec_instruction = *((uint32_t *)vec_address); 34 | offset = vec_instruction & LDR_OFFSET; 35 | instruction = vec_instruction & LDR_INSTRCTION; 36 | 37 | if ((instruction != LDR_PC_PLUS) && 38 | (instruction != LDR_PC_MINUS)) //LDR pc, [pc, +/-] 39 | { 40 | puts("The instruction in vec_address is unrecognized\n"); 41 | return 0x0badc0de; 42 | } 43 | 44 | jumptable = (unsigned*)(offset + vec_address + 0x08); 45 | *handler_location = (unsigned*)(*jumptable); 46 | 47 | //Save system's handler instruction 48 | *instruction1 = *(*handler_location); 49 | *instruction2 = *((*handler_location) + 1); 50 | 51 | //Hijacking SWI handler 52 | *(*handler_location) = LDR_PC_MINUS_FOUR; //LDR pc, [pc, #-4] 53 | *((*handler_location) + 1) = (uint32_t)new_address; 54 | 55 | return 0; 56 | } 57 | 58 | void restore_handler(uint32_t *handler_location, uint32_t instruction1, uint32_t instruction2) 59 | { 60 | //Restore system's SWI handler 61 | *handler_location = instruction1; 62 | *(handler_location + 1) = instruction2; 63 | } 64 | -------------------------------------------------------------------------------- /lab4/kernel/arm/interrupt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file interrupt.c 3 | * 4 | * @brief interrupt related routines 5 | * 6 | * @author Huacong Cai 7 | * @author Qinyu Tong 8 | * 9 | * @date 2014-11-24 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "arm_i.h" 21 | 22 | #define IRQ_VEC 0x18 23 | 24 | uint32_t old_irq_instruction1; 25 | uint32_t old_irq_instruction2; 26 | uint32_t *old_irq_location; 27 | 28 | extern volatile unsigned tick_counter; 29 | 30 | void init_interrupt(void) 31 | { 32 | 33 | install_handler(IRQ_VEC, (uint32_t *)&irq_handler, &old_irq_location, 34 | &old_irq_instruction1, &old_irq_instruction2); 35 | 36 | dev_int_on = TRUE; //turn on device interrupts 37 | } 38 | 39 | void destroy_interrupt(void) 40 | { 41 | //disable interrupt 42 | disable_interrupts(); 43 | 44 | //restore irq handler 45 | restore_handler(old_irq_location, old_irq_instruction1, old_irq_instruction2); 46 | } 47 | 48 | void c_irq_handler (void) 49 | { 50 | volatile unsigned int osmr; 51 | 52 | /*increase the tick counter*/ 53 | tick_counter++; 54 | 55 | if (dev_int_on == TRUE) { 56 | dev_update(tick_counter * OS_TIMER_RESOLUTION); 57 | } 58 | 59 | /*increase OSMR a time interval*/ 60 | osmr = reg_read(OSTMR_OSMR_ADDR(0)); 61 | osmr += OSMR_INTERVAL; 62 | reg_write(OSTMR_OSMR_ADDR(0), osmr); 63 | 64 | reg_set(OSTMR_OSSR_ADDR, OSTMR_OSSR_M0); /*acknowledge IRQ*/ 65 | } 66 | -------------------------------------------------------------------------------- /lab4/kernel/arm/kernel.mk: -------------------------------------------------------------------------------- 1 | ARM_OBJS := reg.o psr.o asm_irq_handler.o asm_swi_handler.o enter_user_mode.o handler.o interrupt.o swi.o timer.o 2 | ARM_OBJS := $(ARM_OBJS:%=$(KDIR)/arm/%) 3 | 4 | KOBJS += $(ARM_OBJS) 5 | -------------------------------------------------------------------------------- /lab4/kernel/arm/psr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define IMPLEMENTATION 4 | #include 5 | -------------------------------------------------------------------------------- /lab4/kernel/arm/reg.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define IMPLEMENTATION 4 | #include 5 | -------------------------------------------------------------------------------- /lab4/kernel/arm/swi.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file swi.c 3 | * 4 | * @brief swi related routines 5 | * 6 | * @author Huacong Cai 7 | * @author Qinyu Tong 8 | * 9 | * @date 2014-11-24 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "arm_i.h" 19 | 20 | #define SWI_VEC 0x08 21 | 22 | uint32_t old_swi_instruction1; 23 | uint32_t old_swi_instruction2; 24 | uint32_t *old_swi_location; 25 | 26 | void swi_exit(int status); 27 | 28 | void init_swi(void) 29 | { 30 | install_handler(SWI_VEC, (uint32_t *)&swi_handler, &old_swi_location, 31 | &old_swi_instruction1, &old_swi_instruction2); 32 | } 33 | 34 | void destroy_swi(void) 35 | { 36 | //restore swi 37 | restore_handler(old_swi_location, old_swi_instruction1, old_swi_instruction2); 38 | } 39 | 40 | //Handle swi according to swi number 41 | void swi_dispatch(unsigned swi_num, struct ex_context* regs) 42 | { 43 | switch (swi_num) 44 | { 45 | case READ_SWI: 46 | (regs->r0) = read_syscall((int)(regs->r0), (char *)(regs->r1), (size_t)(regs->r2)); 47 | break; 48 | 49 | case WRITE_SWI: 50 | (regs->r0) = write_syscall((int)(regs->r0), (const char *)(regs->r1), (size_t)(regs->r2)); 51 | break; 52 | 53 | case TIME_SWI: 54 | (regs->r0) = time_syscall(); 55 | break; 56 | 57 | case SLEEP_SWI: 58 | sleep_syscall((unsigned long)(regs->r0)); 59 | break; 60 | 61 | case CREATE_SWI: 62 | (regs->r0) = task_create((task_t*)(regs->r0), (size_t)(regs->r1)); 63 | break; 64 | 65 | case MUTEX_CREATE: 66 | (regs->r0) = mutex_create(); 67 | break; 68 | 69 | case MUTEX_LOCK: 70 | (regs->r0) = mutex_lock((int)(regs->r0)); 71 | break; 72 | 73 | case MUTEX_UNLOCK: 74 | (regs->r0) = mutex_unlock((int)(regs->r0)); 75 | break; 76 | 77 | case EVENT_WAIT: 78 | (regs->r0) = event_wait((unsigned)(regs->r0)); 79 | break; 80 | 81 | default: 82 | printf("SWI number is unrecognized\n"); 83 | invalid_syscall(swi_num); 84 | break; 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /lab4/kernel/arm/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.c 3 | * 4 | * timer setup: 5 | * Set ICMR to remove mask on OSMR0 interrupt, then set OSMR0 to first time interval. 6 | * After that, set OIER, enable a OSMR0 match to generate an interrupt, then set OSCR to zero. 7 | * 8 | * @author Huacong Cai 9 | * @author Qinyu Tong 10 | * 11 | * @date 2014-11-24 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | extern volatile unsigned tick_counter; 21 | 22 | uint32_t icmr; 23 | uint32_t osmr0; 24 | 25 | void init_timer(void) 26 | { 27 | /*save ICMR*/ 28 | icmr = reg_read(INT_ICMR_ADDR); 29 | 30 | /*set ICMR to remove mask on OSMR0 interrupt*/ 31 | reg_write(INT_ICMR_ADDR, 1 << INT_OSTMR_0); 32 | 33 | /*ICLR does not need to set since its default is IRQ-enabled*/ 34 | 35 | /*save OSMR0*/ 36 | osmr0 = reg_read(OSTMR_OSMR_ADDR(0)); 37 | /*set OSMR0 to time interval*/ 38 | reg_write(OSTMR_OSMR_ADDR(0), OSMR_INTERVAL); 39 | 40 | /*set OIER, enable a OSMR0 match to generate an interrupt*/ 41 | reg_set(OSTMR_OIER_ADDR, OSTMR_OIER_E0); 42 | 43 | /*set OSCR to zero*/ 44 | reg_write(OSTMR_OSCR_ADDR, 0); 45 | 46 | tick_counter = 0; 47 | } 48 | 49 | void destroy_timer(void) 50 | { 51 | /*restore ICMR*/ 52 | reg_write(INT_ICMR_ADDR, icmr); 53 | 54 | /*restore OSMR0*/ 55 | reg_write(OSTMR_OSMR_ADDR(0), osmr0); 56 | 57 | /*disable OIER*/ 58 | reg_clear(OSTMR_OIER_ADDR, OSTMR_OIER_E0); 59 | } 60 | -------------------------------------------------------------------------------- /lab4/kernel/assert.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file assert.c 3 | * 4 | * @brief Assertion and debugging infrastructure. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | void panic(const char* fmt, ...) 17 | { 18 | va_list list; 19 | 20 | va_start(list, fmt); 21 | // XXX This is not working... fix it later. 22 | //vprintf(fmt, list); 23 | printf("PANIC!"); 24 | va_end(list); 25 | 26 | disable_interrupts(); 27 | 28 | while(1); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /lab4/kernel/ctype.c: -------------------------------------------------------------------------------- 1 | /** @file ctype.c 2 | * 3 | * @brief Implementation of inline ctype.h functions. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | 9 | #define IMPLEMENTATION 10 | #include 11 | -------------------------------------------------------------------------------- /lab4/kernel/device.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file device.c 3 | * 4 | * @brief Implements simulated devices. 5 | * 6 | * @author Huacong Cai 7 | * @author Qinyu Tong 8 | * 9 | * @date 2014-11-24 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /** 23 | * @brief Fake device maintainence structure. 24 | * Since our tasks are periodic, we can represent 25 | * tasks with logical devices. 26 | * These logical devices should be signalled periodically 27 | * so that you can instantiate a new job every time period. 28 | * Devices are signaled by calling dev_update 29 | * on every timer interrupt. In dev_update check if it is 30 | * time to create a tasks new job. If so, make the task runnable. 31 | * There is a wait queue for every device which contains the tcbs of 32 | * all tasks waiting on the device event to occur. 33 | */ 34 | 35 | struct dev 36 | { 37 | tcb_t* sleep_queue; 38 | unsigned long next_match; 39 | }; 40 | typedef struct dev dev_t; 41 | 42 | /* devices will be periodically signaled at the following frequencies */ 43 | const unsigned long dev_freq[NUM_DEVICES] = {100, 200, 500, 50}; 44 | static dev_t devices[NUM_DEVICES]; 45 | volatile bool_e dev_int_on; //turn on/off device interrupts (dev_update) 46 | 47 | /** 48 | * @brief Initialize the sleep queues and match values for all devices. 49 | */ 50 | void dev_init(void) 51 | { 52 | /* the following line is to get rid of the warning and should not be needed */ 53 | int i; 54 | for (i = 0; i < NUM_DEVICES; i++) { 55 | devices[i].sleep_queue = NULL; 56 | devices[i].next_match = dev_freq[i]; 57 | } 58 | } 59 | 60 | 61 | /** 62 | * @brief Puts a task to sleep on the sleep queue until the next 63 | * event is signalled for the device. 64 | * 65 | * @param dev Device number. 66 | */ 67 | void dev_wait(unsigned int dev __attribute__((unused))) 68 | { 69 | tcb_t* cur_tcb; 70 | 71 | disable_device_interrupts(); 72 | 73 | cur_tcb = get_cur_tcb(); 74 | 75 | //insert current task in sleep queue 76 | cur_tcb->sleep_queue = devices[dev].sleep_queue; 77 | devices[dev].sleep_queue = cur_tcb; 78 | 79 | enable_device_interrupts(); 80 | 81 | dispatch_sleep(); //goto sleep state to wait device 82 | } 83 | 84 | 85 | /** 86 | * @brief Signals the occurrence of an event on all applicable devices. 87 | * This function should be called on timer interrupts to determine that 88 | * the interrupt corresponds to the event frequency of a device. If the 89 | * interrupt corresponded to the interrupt frequency of a device, this 90 | * function should ensure that the task is made ready to run 91 | */ 92 | void dev_update(unsigned long millis __attribute__((unused))) 93 | { 94 | tcb_t* temp_tcb; 95 | int i; 96 | 97 | disable_device_interrupts(); 98 | 99 | for (i = 0; i < NUM_DEVICES; i++) { 100 | if (devices[i].next_match <= millis) { //if frequency match device's frequncy 101 | devices[i].next_match += dev_freq[i]; //update device's next match 102 | while (devices[i].sleep_queue != NULL) { 103 | /*make tasks ready to run*/ 104 | temp_tcb = devices[i].sleep_queue; 105 | devices[i].sleep_queue = devices[i].sleep_queue->sleep_queue; 106 | temp_tcb->sleep_queue = NULL; 107 | runqueue_add(temp_tcb, temp_tcb->cur_prio); 108 | } 109 | } 110 | } 111 | enable_device_interrupts(); 112 | 113 | dispatch_save(); 114 | 115 | } 116 | 117 | /** 118 | * @brief clear old device sleep queues. 119 | */ 120 | void dev_clear(void) 121 | { 122 | int i; 123 | 124 | disable_device_interrupts(); 125 | 126 | for (i = 0; i < NUM_DEVICES; i++) { 127 | devices[i].sleep_queue = NULL; 128 | } 129 | 130 | enable_device_interrupts(); 131 | } 132 | 133 | -------------------------------------------------------------------------------- /lab4/kernel/hexdump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | /* 26 | * Print a buffer hexdump style. Example: 27 | * 28 | * .---------------------------------------------------------------------------. 29 | * | 00000000 2e2f612e 6f757400 5445524d 3d787465 ./a.out.TERM=xte | 30 | * | 00000010 726d0048 4f4d453d 2f616673 2f63732e rm.HOME=/afs/cs. | 31 | * | 00000020 75746168 2e656475 2f686f6d 652f6c6f utah.edu/home/lo | 32 | * | 00000030 6d657700 5348454c 4c3d2f62 696e2f74 mew.SHELL=/bin/t | 33 | * | 00000040 63736800 4c4f474e 414d453d 6c6f6d65 csh.LOGNAME=lome | 34 | * | 00000050 77005553 45523d6c 6f6d6577 00504154 w.USER=lomew.PAT | 35 | * | 00000060 483d2f61 66732f63 732e7574 61682e65 H=/afs/cs.utah.e | 36 | * | 00000070 64752f68 6f6d652f 6c6f6d65 772f6269 du/home/lomew/bi | 37 | * | 00000080 6e2f4073 79733a2f 6166732f 63732e75 n/@sys:/afs/cs.u | 38 | * | 00000090 7461682e 6564 tah.ed | 39 | * `---------------------------------------------------------------------------' 40 | * 41 | * It might be useful to have an option for printing out little-endianly. 42 | * Adapted from Godmar's hook.c. 43 | */ 44 | void hexdump(void *buf, size_t len) 45 | { 46 | size_t i, j; 47 | char *b = (char *)buf; 48 | 49 | printf(".---------------------------------------------------------------------------.\n"); 50 | for (i = 0; i < len; i += 16) { 51 | printf("| %08lx ", i); 52 | for (j = i; j < i+16; j++) { 53 | if (j % 4 == 0) 54 | printf(" "); 55 | if (j >= len) 56 | printf(" "); 57 | else 58 | printf("%02x", (unsigned char)b[j]); 59 | } 60 | 61 | printf(" "); 62 | for (j = i; j < i+16; j++) 63 | if (j >= len) 64 | printf(" "); 65 | else 66 | printf("%c", isgraph(b[j]) ? b[j] : '.'); 67 | printf(" |\n"); 68 | } 69 | printf("`---------------------------------------------------------------------------'\n"); 70 | } 71 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/exception.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file exception.h 3 | * 4 | * @brief Definitions for ARM exception vectoring. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-07-23 9 | */ 10 | 11 | #ifndef _EXCEPTION_H_ 12 | #define _EXCEPTION_H_ 13 | 14 | #define EX_RESET 0 15 | #define EX_UD 1 16 | #define EX_SWI 2 17 | #define EX_FABRT 3 18 | #define EX_DABRT 4 19 | #define EX_IRQ 6 20 | #define EX_FIQ 7 21 | #define NUM_EXCEPTIONS 8 22 | 23 | #ifndef ASSEMBLER 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | /* Register context. */ 30 | struct ex_context 31 | { 32 | uint32_t r0; 33 | uint32_t r1; 34 | uint32_t r2; 35 | uint32_t r3; 36 | uint32_t r4; 37 | uint32_t r5; 38 | uint32_t r6; 39 | uint32_t r7; 40 | uint32_t r8; 41 | uint32_t r9; 42 | uint32_t r10; 43 | uint32_t r11; 44 | uint32_t r12; 45 | }; 46 | typedef struct ex_context ex_context_t; 47 | 48 | 49 | void init_exception(void); 50 | void destroy_exception(void); 51 | void install_exception_handler(unsigned int exn_num, void (*handler)(void)) 52 | __attribute__((nonnull)); 53 | 54 | INLINE void enable_interrupts(void) 55 | { 56 | uint32_t cpsr; 57 | asm volatile ("mrs %0, cpsr" : "=r" (cpsr)); 58 | cpsr &= ~(PSR_IRQ | PSR_FIQ); 59 | asm volatile ("msr cpsr_c, %0" : : "r" (cpsr) : "memory", "cc"); 60 | } 61 | 62 | INLINE void disable_interrupts(void) 63 | { 64 | uint32_t cpsr; 65 | asm volatile ("mrs %0, cpsr" : "=r" (cpsr)); 66 | cpsr |= PSR_IRQ | PSR_FIQ; 67 | asm volatile ("msr cpsr_c, %0" : : "r" (cpsr) : "memory", "cc"); 68 | } 69 | 70 | #endif /* ASSEMBLER */ 71 | 72 | #endif /* _EXCEPTION_H_ */ 73 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/interrupt.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file interrupt.h 3 | * 4 | * @brief Definitions for the interrupt controller. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-07-21 9 | * 10 | * @note The addresses here are the addresses stated in the Intel PXA255 11 | * Processor Developer's Manual minus 0x40000000. This is so that 12 | * this memory region can be relocated if we ever turn on the MMU. 13 | */ 14 | 15 | #ifndef _INTERRUPT_H_ 16 | #define _INTERRUPT_H_ 17 | 18 | #define INT_ICIP_ADDR 0x00D00000 /* Interrupt Controller IRQ Pending Register */ 19 | #define INT_ICMR_ADDR 0x00D00004 /* Interrupt Controller Mask Register */ 20 | #define INT_ICLR_ADDR 0x00D00008 /* Interrupt Controller Level Register */ 21 | #define INT_ICFP_ADDR 0x00D0000C /* Interrupt Controller FIQ Pending Register */ 22 | #define INT_ICPR_ADDR 0x00D00010 /* Interrupt Controller Pending Register */ 23 | 24 | #define INT_ICCR_ADDR 0x00D00014 /* Interrupt Controller Control Register */ 25 | #define INT_ICCR_DIM 0x00000001 /* Activate Idle Mask and ICMR */ 26 | 27 | #define INT_HUART 7 /* HUART Service Request Interrupt */ 28 | #define INT_GPIO_0 8 /* GPIO[0] Edge Detect Interrupt */ 29 | #define INT_GPIO_1 9 /* GPIO[1] Edge Detect Interrupt */ 30 | #define INT_GPIO_HI 10 /* GPIO[84:2] Edge Detect Interrupt */ 31 | #define INT_USB 11 /* USB Service Interrupt */ 32 | #define INT_PMU 12 /* PMU Interrupt */ 33 | #define INT_I2S 13 /* I2S Interrupt */ 34 | #define INT_AC97 14 /* AC97 Interrupt */ 35 | #define INT_NSSP 16 /* Network SSP Service Request Interrupt */ 36 | #define INT_LCD 17 /* LCD Controller Service Request Interrupt */ 37 | #define INT_I2C 18 /* I2C Service Request Interrupt */ 38 | #define INT_ICP 19 /* ICP Transmit/Receive/Error Interrupt */ 39 | #define INT_STUART 20 /* STUART Transmit/Receive/Error Interrupt */ 40 | #define INT_BTUART 21 /* BTUART Transmit/Receive/Error Interrupt */ 41 | #define INT_FFUART 22 /* FFUART Transmit/Receive/Error Interrupt */ 42 | #define INT_MMC 23 /* MMC Status/Error Detection Interrupt */ 43 | #define INT_SSP 24 /* SSP Service Request Interrupt */ 44 | #define INT_DMA 25 /* DMA Channel Service Request Interrupt */ 45 | #define INT_OSTMR_0 26 /* OS Timer Match Register 0 Interrupt */ 46 | #define INT_OSTMR_1 27 /* OS Timer Match Register 1 Interrupt */ 47 | #define INT_OSTMR_2 28 /* OS Timer Match Register 2 Interrupt */ 48 | #define INT_OSTMR_3 29 /* OS Timer Match Register 3 Interrupt */ 49 | #define INT_RTC_HZ 30 /* RTC HZ Clock Tick Interrupt */ 50 | #define INT_RTC_MATCH 31 /* RTC Alarm Match Register Interrupt */ 51 | 52 | #define INT_RESERVED_MASK 0x0000807f /* Reserved bits that must be ignored */ 53 | 54 | #define NUM_INTERRUPTS 32 55 | 56 | #ifndef ASSEMBLER 57 | 58 | void interrupt_panic(unsigned int int_num) __attribute__((noreturn)); 59 | void init_interrupt(void); 60 | void destroy_interrupt(void); 61 | void irq_handler(void); 62 | void c_irq_handler (void); 63 | void request_reschedule(void); 64 | void install_int_handler(unsigned int int_num, void (*int_handler)(unsigned int)) 65 | __attribute__((nonnull)); 66 | 67 | #endif /* ASSEMBLER */ 68 | 69 | #endif /* _INTERRUPT_H_ */ 70 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/physmem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file physmem.h 3 | * 4 | * @brief Definitions for Intel PXA-255 physical memory layout. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-11-16 9 | */ 10 | 11 | #ifndef _PHYSMEM_H_ 12 | #define _PHYSMEM_H_ 13 | 14 | #define FLASH_START_ADDR 0x00000000 15 | #define FLASH_END_ADDR 0x01000000 16 | #define RAM_START_ADDR 0xa0000000 17 | #define RAM_END_ADDR 0xa4000000 18 | 19 | #ifndef ASSEMBLER 20 | 21 | #endif /* ASSEMBLER */ 22 | 23 | #endif /* _PHYSMEM_H_ */ 24 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/psr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file psr.h 3 | * 4 | * @brief Definitions for ARM program state registers (CPSR and SPSRs). 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-08-13 9 | */ 10 | 11 | #ifndef _PSR_H_ 12 | #define _PSR_H_ 13 | 14 | #define PSR_NEG 0x80000000 15 | #define PSR_ZERO 0x40000000 16 | #define PSR_CARRY 0x20000000 17 | #define PSR_OFLW 0x10000000 18 | #define PSR_IRQ 0x00000080 19 | #define PSR_FIQ 0x00000040 20 | #define PSR_MODE 0x0000001f 21 | 22 | #define PSR_MODE_USR 0x10 23 | #define PSR_MODE_FIQ 0x11 24 | #define PSR_MODE_IRQ 0x12 25 | #define PSR_MODE_SVC 0x13 26 | #define PSR_MODE_ABT 0x17 27 | #define PSR_MODE_UND 0x1b 28 | #define PSR_MODE_SYS 0x1b 29 | 30 | #ifndef ASSEMBLER 31 | 32 | #include 33 | 34 | INLINE uint32_t read_cpsr(void) 35 | { 36 | uint32_t cpsr; 37 | asm volatile ("mrs %0, cpsr" : "=r" (cpsr)); 38 | return cpsr; 39 | } 40 | 41 | #endif /* ASSEMBLER */ 42 | #endif /* _EXCEPTION_H_ */ 43 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/reg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file reg.h 3 | * 4 | * @brief Generic memory mapped register access routines. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-07-08 9 | */ 10 | 11 | #ifndef _REG_H_ 12 | #define _REG_H_ 13 | 14 | #include 15 | #include 16 | 17 | #define PERIPHERAL_BASE 0x40000000 18 | 19 | INLINE uint32_t reg_read(size_t addr) 20 | { 21 | return *((volatile uint32_t*)(PERIPHERAL_BASE + addr)); 22 | } 23 | 24 | INLINE void reg_write(size_t addr, uint32_t data) 25 | { 26 | *((volatile uint32_t*)(PERIPHERAL_BASE + addr)) = data; 27 | } 28 | 29 | INLINE void reg_set(size_t addr, uint32_t flags) 30 | { 31 | volatile uint32_t* reg = (volatile uint32_t*)(PERIPHERAL_BASE + addr); 32 | *reg = *reg | flags; 33 | } 34 | 35 | INLINE void reg_clear(size_t addr, uint32_t flags) 36 | { 37 | volatile uint32_t* reg = (volatile uint32_t*)(PERIPHERAL_BASE + addr); 38 | *reg = *reg & (~flags); 39 | } 40 | 41 | #endif /* _REG_H_ */ 42 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/swi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file swi.h 3 | * 4 | * @brief Definitions for the software interrupt handler. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-11-18 9 | */ 10 | 11 | #ifndef _SWI_H_ 12 | #define _SWI_H_ 13 | 14 | #ifndef ASSEMBLER 15 | 16 | #include 17 | 18 | void init_swi(void); 19 | void destroy_swi(void); 20 | void swi_handler(void); 21 | void swi_dispatch(unsigned int swi_num, struct ex_context* regs); 22 | 23 | #endif /* ASSEMBLER */ 24 | 25 | #endif /* _SWI_H_ */ 26 | -------------------------------------------------------------------------------- /lab4/kernel/include/arm/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file timer.h 3 | * 4 | * @brief Definitions for the OS timer. 5 | * 6 | * @author Kartik Subramanian 7 | * 8 | * @date 2008-07-07 9 | * 10 | * @note The addresses here are the addresses stated in the Intel PXA255 11 | * Processor Developer's Manual minus 0x40000000. This is so that 12 | * this memory region can be relocated if we ever turn on the MMU. 13 | */ 14 | 15 | #ifndef _TIMER_H_ 16 | #define _TIMER_H_ 17 | 18 | #define OSTMR_OSMR_ADDR(x) (0x00A00000 + (x)*4) /* OS Timer Match Register */ 19 | 20 | #define OSTMR_OSCR_ADDR 0x00A00010 /* OS Timer Count Register */ 21 | 22 | #define OSTMR_OSSR_ADDR 0x00A00014 /* OS Timer Status Register */ 23 | #define OSTMR_OSSR_M0 0x00000001 /* Matched 0 */ 24 | #define OSTMR_OSSR_M1 0x00000002 /* Matched 1 */ 25 | #define OSTMR_OSSR_M2 0x00000004 /* Matched 2 */ 26 | #define OSTMR_OSSR_M3 0x00000008 /* Matched 3 */ 27 | 28 | #define OSTMR_OWER_ADDR 0x00A00018 /* OS Timer Watchdog Enable Register */ 29 | #define OSTMR_OWER_WME 0x00000001 /* Watchdog mode enable */ 30 | 31 | #define OSTMR_OIER_ADDR 0x00A0001C /* OS Timer Interrupt Enable Register */ 32 | #define OSTMR_OIER_E0 0x00000001 /* Enable match 0 */ 33 | #define OSTMR_OIER_E1 0x00000002 /* Enable match 1 */ 34 | #define OSTMR_OIER_E2 0x00000004 /* Enable match 2 */ 35 | #define OSTMR_OIER_E3 0x00000008 /* Enable match 3 */ 36 | 37 | #define OSTMR_FREQ 3686400 /* Oscillator frequency in hz */ 38 | 39 | #ifndef ASSEMBLER 40 | 41 | void init_timer(void); 42 | void destroy_timer(void); 43 | void timer_handler(unsigned int int_num); 44 | unsigned long get_ticks(void); 45 | unsigned long get_millis(void); 46 | 47 | #endif /* ASSEMBLER */ 48 | 49 | #endif /* _TIMER_H_ */ 50 | -------------------------------------------------------------------------------- /lab4/kernel/include/asm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file asm.h 3 | * 4 | * @brief Common macros for asm routines. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #ifndef _ASM_H_ 10 | #define _ASM_H_ 11 | 12 | #define ARG0 r0 13 | #define ARG1 r1 14 | #define ARG2 r2 15 | #define ARG3 r3 16 | 17 | #define ARG4 [sp, #0] 18 | #define ARG5 [sp, #4] 19 | #define ARG6 [sp, #8] 20 | #define ARG7 [sp, #8] 21 | 22 | 23 | #define ALIGN .align 2 24 | #define ALIGN8 .align 3 25 | #define GLOBAL(x) .global x; x ## : 26 | 27 | #define FUNCSYM(x) .type x,%function 28 | #define DATASYM(x) .type x,%object 29 | #define SIZE(x,s) .size x, s 30 | 31 | #define FUNC(x) .text ; ALIGN ; FUNCSYM(x) ; GLOBAL(x) 32 | #define DATA(x,s) .data ; ALIGN ; DATASYM(x) ; SIZE(x,s) ; GLOBAL(x) 33 | 34 | #define BSS_WORD32(x) .comm x, 4, 4 35 | 36 | #define CRASH(x, r) ldr r, =x; ldr r, [r]; 37 | 38 | #endif /* _ASM_H_ */ 39 | -------------------------------------------------------------------------------- /lab4/kernel/include/assert.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file assert.h 3 | * 4 | * @brief Assertion and debugging infrastructure. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #ifndef _ASSERT_H_ 10 | #define _ASSERT_H_ 11 | 12 | #ifdef NDEBUG 13 | 14 | #define assert(e) ((void)0) 15 | #define crash 16 | 17 | #else 18 | 19 | #include 20 | 21 | void panic(const char* fmt, ...) __attribute__((noreturn, format (printf, 1, 2))); 22 | void hexdump(void* buf, size_t len); 23 | 24 | #define crash \ 25 | ((void)(*(volatile char*)0xdeadbeef)) 26 | 27 | #include 28 | #define assert(e) \ 29 | ((void)((e) ? 0 : (printf("Assertion Failure at %s:%d\n%s", __FILE__, \ 30 | __LINE__, #e), panic(" "), 0))) 31 | /*#define assert(e) \ 32 | ((void)((e) ? 0 : (panic("Assertion Failure at %s:%d\n%s", __FILE__, \ 33 | __LINE__, #e), 0))) */ 34 | #endif 35 | 36 | #endif /* _ASSERT_H_ */ 37 | 38 | -------------------------------------------------------------------------------- /lab4/kernel/include/bits/errno.h: -------------------------------------------------------------------------------- 1 | /* From linux-2.6.18/include/asm-generic/errno-base.h */ 2 | 3 | #ifndef BITS_ERRNO_H 4 | #define BITS_ERRNO_H 5 | 6 | #define EPERM 1 /* Operation not permitted */ 7 | #define ENOENT 2 /* No such file or directory */ 8 | #define ESRCH 3 /* No such process */ 9 | #define EINTR 4 /* Interrupted system call */ 10 | #define EIO 5 /* I/O error */ 11 | #define ENXIO 6 /* No such device or address */ 12 | #define E2BIG 7 /* Argument list too long */ 13 | #define ENOEXEC 8 /* Exec format error */ 14 | #define EBADF 9 /* Bad file number */ 15 | #define ECHILD 10 /* No child processes */ 16 | #define EAGAIN 11 /* Try again */ 17 | #define ENOMEM 12 /* Out of memory */ 18 | #define EACCES 13 /* Permission denied */ 19 | #define EFAULT 14 /* Bad address */ 20 | #define ENOTBLK 15 /* Block device required */ 21 | #define EBUSY 16 /* Device or resource busy */ 22 | #define EEXIST 17 /* File exists */ 23 | #define EXDEV 18 /* Cross-device link */ 24 | #define ENODEV 19 /* No such device */ 25 | #define ENOTDIR 20 /* Not a directory */ 26 | #define EISDIR 21 /* Is a directory */ 27 | #define EINVAL 22 /* Invalid argument */ 28 | #define ENFILE 23 /* File table overflow */ 29 | #define EMFILE 24 /* Too many open files */ 30 | #define ENOTTY 25 /* Not a typewriter */ 31 | #define ETXTBSY 26 /* Text file busy */ 32 | #define EFBIG 27 /* File too large */ 33 | #define ENOSPC 28 /* No space left on device */ 34 | #define ESPIPE 29 /* Illegal seek */ 35 | #define EROFS 30 /* Read-only file system */ 36 | #define EMLINK 31 /* Too many links */ 37 | #define EPIPE 32 /* Broken pipe */ 38 | #define EDOM 33 /* Math argument out of domain of func */ 39 | #define ERANGE 34 /* Math result not representable */ 40 | #define EDEADLOCK 58 /* File locking deadlock error */ 41 | 42 | #define ESCHED 100 /* Unable to schedule */ 43 | 44 | #endif /* BITS_ERRNO_H */ 45 | -------------------------------------------------------------------------------- /lab4/kernel/include/bits/fileno.h: -------------------------------------------------------------------------------- 1 | /** @fileno.h 2 | * 3 | * @brief Defines stdin/stdout/stderr file descriptor numbers 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:34:56 -0400 7 | */ 8 | 9 | #ifndef BITS_FILENO_H 10 | #define BITS_FILENO_H 11 | 12 | #define STDIN_FILENO 0 13 | #define STDOUT_FILENO 1 14 | #define STDERR_FILENO 2 15 | 16 | #endif /* BITS_FILENO_H */ 17 | -------------------------------------------------------------------------------- /lab4/kernel/include/bits/swi.h: -------------------------------------------------------------------------------- 1 | /** @file swi.h 2 | * 3 | * @brief Defines syscall numbers used in SWI instructions 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:36:02 -0400 7 | * 8 | * @author Kartik Subramanian 9 | * @date 2008-10-31 10 | */ 11 | 12 | #ifndef BITS_SWI_H 13 | #define BITS_SWI_H 14 | 15 | #define SWI_BASE 0x900000 16 | 17 | #define READ_SWI (SWI_BASE + 3) 18 | #define WRITE_SWI (SWI_BASE + 4) 19 | 20 | /* The following are not linux compatible */ 21 | #define TIME_SWI (SWI_BASE + 6) 22 | #define SLEEP_SWI (SWI_BASE + 7) 23 | 24 | #define CREATE_SWI (SWI_BASE + 10) 25 | 26 | #define MUTEX_CREATE (SWI_BASE + 15) 27 | #define MUTEX_LOCK (SWI_BASE + 16) 28 | #define MUTEX_UNLOCK (SWI_BASE + 17) 29 | 30 | #define EVENT_WAIT (SWI_BASE + 20) 31 | 32 | #endif /* BITS_SWI_H */ 33 | -------------------------------------------------------------------------------- /lab4/kernel/include/config.h: -------------------------------------------------------------------------------- 1 | /** @file config.h 2 | * 3 | * @brief A set of common OS configuration flags. This is to control overall 4 | * OS behavior and not behavior of a particular modules. 5 | * 6 | * @author Huacong Cai 7 | * @author Qinyu Tong 8 | * @date 2014-11-24 9 | */ 10 | 11 | #ifndef _CONFIG_H_ 12 | #define _CONFIG_H_ 13 | 14 | #define OS_TICKS_PER_SEC 100 /* Set the number of ticks in one second */ 15 | #define OS_TIMER_RESOLUTION (1000/OS_TICKS_PER_SEC) /* Timer resolution in ms */ 16 | #define OSMR_INTERVAL (3250000/OS_TICKS_PER_SEC) /* Value of OSMR increases every tick */ 17 | 18 | #define LOAD_ADDR 0xa0000000 19 | #define USR_STACK 0xa3000000 20 | 21 | #define USR_START_ADDR 0xa0000000 22 | #define USR_END_ADDR 0xa3000000 23 | 24 | #define OS_KSTACK_SIZE 4096 25 | #define OS_USTACK_ALIGN 1024 26 | #define OS_IRQ_STACK_SIZE 128 27 | 28 | /* OS_MAX_TASKS must be atleast 8 and must be atmost 64 */ 29 | #define IDLE_PRIO 63 30 | #define OS_MAX_TASKS 64 31 | #define OS_AVAIL_TASKS 63 32 | 33 | /* OS_NUM_MUTEX must be at lease 32 */ 34 | #define OS_NUM_MUTEX 32 35 | 36 | #endif /* _CONFIG_H_ */ 37 | -------------------------------------------------------------------------------- /lab4/kernel/include/ctype.h: -------------------------------------------------------------------------------- 1 | /** @file ctype.h 2 | * 3 | * @brief Predicates for characters. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | 9 | #ifndef _CTYPE_H_ 10 | #define _CTYPE_H_ 11 | 12 | #include 13 | 14 | INLINE int __attribute__((const)) isascii(int c) 15 | { 16 | return (c >= 0) && (c <= 127); 17 | } 18 | 19 | INLINE int __attribute__((const)) iscntrl(int c) 20 | { 21 | return (c < ' ') || (c > 126); 22 | } 23 | 24 | INLINE int __attribute__((const)) isdigit(int c) 25 | { 26 | return (c >= '0') && (c <= '9'); 27 | } 28 | 29 | INLINE int __attribute__((const)) isgraph(int c) 30 | { 31 | return (c > ' ') && (c <= 126); 32 | } 33 | 34 | INLINE int __attribute__((const)) islower(int c) 35 | { 36 | return (c >= 'a') && (c <= 'z'); 37 | } 38 | 39 | INLINE int __attribute__((const)) isprint(int c) 40 | { 41 | return (c >= ' ') && (c <= 126); 42 | } 43 | 44 | INLINE int __attribute__((const)) isspace(int c) 45 | { 46 | return (c == ' ') || (c == '\f') || (c == '\n') 47 | || (c == '\n') || (c == '\r') || (c == '\t') || (c == '\v'); 48 | } 49 | 50 | INLINE int __attribute__((const)) isupper(int c) 51 | { 52 | return (c >= 'A') && (c <= 'Z'); 53 | } 54 | 55 | INLINE int __attribute__((const)) isxdigit(int c) 56 | { 57 | return isdigit(c) || 58 | ((c >= 'A') && (c <= 'F')) || 59 | ((c >= 'a') && (c <= 'f')); 60 | } 61 | 62 | INLINE int __attribute__((const)) isalpha(int c) 63 | { 64 | return islower(c) || isupper(c); 65 | } 66 | 67 | INLINE int __attribute__((const)) isalnum(int c) 68 | { 69 | return isalpha(c) || isdigit(c); 70 | } 71 | 72 | INLINE int __attribute__((const)) ispunct(int c) 73 | { 74 | return isgraph(c) && !isalnum(c); 75 | } 76 | 77 | INLINE int __attribute__((const)) toupper(int c) 78 | { 79 | return islower(c) ? c - 'a' + 'A' : c; 80 | } 81 | 82 | INLINE int __attribute__((const)) tolower(int c) 83 | { 84 | return isupper(c) ? c - 'A' + 'a' : c; 85 | } 86 | 87 | #endif /* _CTYPE_H_ */ 88 | -------------------------------------------------------------------------------- /lab4/kernel/include/device.h: -------------------------------------------------------------------------------- 1 | /** @file device.h 2 | * 3 | * @brief Declaration of "simulated devices". 4 | * 5 | * These devices each have an associated condition variable that they signal 6 | * with the given periodicity. Each condition variable also has an associated 7 | * mutex of the same index. 8 | * 9 | * @author Kartik Subramanian 10 | * @date 2008-12-01 11 | */ 12 | 13 | #ifndef _DEVICE_H_ 14 | #define _DEVICE_H_ 15 | 16 | #include 17 | #include 18 | #include 19 | #define NUM_DEVICES 4 20 | 21 | extern const unsigned long dev_freq[NUM_DEVICES]; 22 | extern volatile bool_e dev_int_on; 23 | 24 | void dev_init(void); 25 | void dev_wait(unsigned int dev); 26 | void dev_update(unsigned long num_millis); 27 | void dev_clear(void); 28 | 29 | INLINE void disable_device_interrupts(void) { 30 | dev_int_on = FALSE; 31 | } 32 | 33 | INLINE void enable_device_interrupts(void) { 34 | dev_int_on = TRUE; 35 | } 36 | 37 | #endif /* _DEVICE_H_ */ 38 | 39 | -------------------------------------------------------------------------------- /lab4/kernel/include/inline.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file inline.h 3 | * 4 | * @brief GCC specific dances to guarantee correct inlining. 5 | * 6 | * Gcc will never generate code for an extern inline function on its own. Any 7 | * occurences of a call to an extern inline function will be expanded inline. 8 | * If the address of an extern inline function is taken, it is counted as an 9 | * external reference. 10 | * 11 | * To use this feature correctly, we put the code for all functions that we want 12 | * to inline in headers as `extern inline' and then put a single copy of the 13 | * function without extern inline in a library file. This will cause most calls 14 | * to the function to get inlined. Any remaining uses of the function (such as 15 | * taking the address of the function) will now refer to the single library copy 16 | * of the function. 17 | * 18 | * @author Kartik Subramanian 19 | * 20 | * @date 2008-07-08 21 | */ 22 | 23 | /* No guards... on purpose! */ 24 | 25 | #ifdef INLINE 26 | #undef INLINE 27 | #endif 28 | 29 | #ifndef IMPLEMENTATION 30 | #define INLINE extern inline 31 | #else 32 | #define INLINE 33 | #endif 34 | -------------------------------------------------------------------------------- /lab4/kernel/include/kernel.h: -------------------------------------------------------------------------------- 1 | /** @file kernel.h 2 | * 3 | * @brief Main kernel -- primary interface. 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * Date: 2014-11-24 8 | */ 9 | 10 | #ifndef KERNEL_H 11 | #define KERNEL_H 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | extern uint32_t global_data; 20 | int valid_addr(const void* start, size_t count, uintptr_t base, uintptr_t bound); 21 | int enter_user_mode(int argc, char *argv[]); 22 | 23 | 24 | #endif /* KERNEL_H */ 25 | -------------------------------------------------------------------------------- /lab4/kernel/include/lock.h: -------------------------------------------------------------------------------- 1 | /** @file lock.h 2 | * 3 | * @brief Declaration of locking and synchronization primitives. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-12-01 7 | * 8 | * @author Junsung Kim 9 | * Veeren Mandalia 10 | * Vikram Gupta 11 | * @date Sat, 06 Dec 2008 05:15:00 -0400 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #ifndef _LOCK_H_ 18 | #define _LOCK_H_ 19 | 20 | struct mutex 21 | { 22 | bool_e bAvailable; /* flag for availability */ 23 | tcb_t* pHolding_Tcb; /* who are using this mutex */ 24 | bool_e bLock; /* 1 for lock/0 for unlock */ 25 | tcb_t* pSleep_queue; /* list of applications waiting for this mutex */ 26 | }; 27 | typedef struct mutex mutex_t; 28 | 29 | struct cond 30 | { 31 | /* FILL THIS IN */ 32 | /* is not handled in this lab */ 33 | }; 34 | typedef struct cond cond_t; 35 | 36 | void mutex_init(void); /* a function for initiating mutexes */ 37 | int mutex_create(void); 38 | int mutex_lock(int mutex); 39 | int mutex_unlock(int mutex); 40 | 41 | #endif /* _LOCK_H_ */ 42 | -------------------------------------------------------------------------------- /lab4/kernel/include/math.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file math.h 3 | * 4 | * @brief Contains interface to integer math routines. 5 | * 6 | * @author Kartik Subramanian 7 | * @date 2008-08-07 8 | */ 9 | 10 | #ifndef _MATH_H_ 11 | #define _MATH_H_ 12 | 13 | unsigned int ilog2(unsigned int x); 14 | unsigned int sum_region(unsigned int* buf, size_t num_words); 15 | 16 | #endif /* _MATH_H_ */ 17 | -------------------------------------------------------------------------------- /lab4/kernel/include/sched.h: -------------------------------------------------------------------------------- 1 | /** @file sched.h 2 | * 3 | * @brief Declares core scheduler and task management routines. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-21 7 | */ 8 | 9 | #ifndef SCHED_H 10 | #define SCHED_H 11 | 12 | #include 13 | #include 14 | 15 | void sched_init(task_t* main_task); 16 | 17 | /* Scheduler invocations */ 18 | void dispatch_save(void); 19 | void dispatch_nosave(void); 20 | void dispatch_sleep(void); 21 | 22 | /* Entry assist */ 23 | void launch_task(void); /* takes lambda and argument in r4, r5 */ 24 | 25 | /* Task initialization */ 26 | void allocate_tasks(task_t** tasks, size_t num_tasks); 27 | int assign_schedule(task_t** tasks, size_t num_tasks); 28 | 29 | /* Current task state */ 30 | uint8_t get_cur_prio(void); 31 | tcb_t* get_cur_tcb(void); 32 | 33 | /* Run-queue/priority management */ 34 | void runqueue_add(tcb_t* tcb, uint8_t prio); 35 | tcb_t* runqueue_remove(uint8_t prio); 36 | uint8_t highest_prio(void); 37 | 38 | #endif /* SCHED_H */ 39 | -------------------------------------------------------------------------------- /lab4/kernel/include/stdarg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdarg.h: Defines variable argument macros & typedef 3 | * 4 | * Author: Mike Kasick 5 | * Date: Sun, 14 Oct 2007 00:12:03 -0400 6 | */ 7 | 8 | #ifndef STDARG_H 9 | #define STDARG_H 10 | 11 | #define va_start(ap, last) __builtin_va_start(ap, last) 12 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 13 | #define va_end(ap) __builtin_va_end(ap) 14 | #define va_copy(dest, src) __builtin_va_copy(dest, src) 15 | 16 | typedef __builtin_va_list va_list; 17 | 18 | #endif /* STDARG_H */ 19 | -------------------------------------------------------------------------------- /lab4/kernel/include/syscall.h: -------------------------------------------------------------------------------- 1 | /** @file syscall.h 2 | * 3 | * @brief Declares the kernel supported syscalls 4 | * 5 | * @author Mike Kasick 6 | * @date Sat, 13 Oct 2007 23:54:45 -0400 7 | */ 8 | 9 | #ifndef SYSCALL_H 10 | #define SYSCALL_H 11 | 12 | #include 13 | #include 14 | 15 | ssize_t read_syscall(int fd, char *buf, size_t count); 16 | ssize_t write_syscall(int fd, const char *buf, size_t count); 17 | 18 | unsigned long time_syscall(void); 19 | void sleep_syscall(unsigned long millis); 20 | 21 | void invalid_syscall(unsigned int num) __attribute__((noreturn)); 22 | 23 | int task_create(task_t* tasks, size_t num_tasks); 24 | int event_wait(unsigned int dev); 25 | 26 | #endif /* SYSCALL_H */ 27 | -------------------------------------------------------------------------------- /lab4/kernel/include/task.h: -------------------------------------------------------------------------------- 1 | /** @file task.h 2 | * 3 | * @brief Declares task maintainence structures. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-19 7 | */ 8 | 9 | #ifndef TASK_H 10 | #define TASK_H 11 | 12 | #include 13 | #include 14 | 15 | /** 16 | * A task takes an arbitrary parameter and begins execution. 17 | * Task function are not allowed to exit or crash under any circumstance. 18 | */ 19 | typedef void (*task_fun_t)(void*); 20 | 21 | struct task 22 | { 23 | task_fun_t lambda; /**< The root function of this task */ 24 | void* data; /**< Argument to the root function */ 25 | void* stack_pos; /**< The starting position of the task's sp */ 26 | unsigned long C; /**< The worst-case computation time */ 27 | unsigned long T; /**< The task's period */ 28 | }; 29 | typedef struct task task_t; 30 | 31 | 32 | /** 33 | * Register context for the scheduler. 34 | * 35 | * No caller saved registers are present. Scratch register is not present. 36 | */ 37 | struct sched_context 38 | { 39 | uint32_t r4; 40 | uint32_t r5; 41 | uint32_t r6; 42 | uint32_t r7; 43 | uint32_t r8; 44 | uint32_t r9; 45 | uint32_t r10; 46 | uint32_t r11; 47 | void* sp; 48 | void* lr; 49 | }; 50 | typedef volatile struct sched_context sched_context_t; 51 | 52 | 53 | struct tcb 54 | { 55 | uint8_t native_prio; /**< The native priority of the task without escalation */ 56 | uint8_t cur_prio; /**< The current priority of the task after priority inheritance */ 57 | sched_context_t context; /**< The task's serialized context -- if not running */ 58 | int holds_lock; /**< 1 if the task is currently owning a lock */ 59 | volatile struct tcb* sleep_queue; /**< If this task is asleep, this is its sleep queue link */ 60 | /** Embed the kernel stack here -- AAPCS wants 8 byte alignment */ 61 | uint32_t kstack[OS_KSTACK_SIZE/sizeof(uint32_t)] 62 | __attribute__((aligned(8))); 63 | uint32_t kstack_high[0]; 64 | }; 65 | typedef volatile struct tcb tcb_t; 66 | 67 | 68 | #endif /* TASK_H */ 69 | -------------------------------------------------------------------------------- /lab4/kernel/include/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file types.h 3 | * 4 | * @brief Standard Integer Types and Limits 5 | * Corresponds to ANSI C99 stdint.h, stddef.h and limits.h 6 | * 7 | * @note Other standard foo that needs to be defined are defined here. 8 | * 9 | * @date 2006-05-21 10 | * @date 2008-10-29 (added limits) 11 | * @author Kartik Subramanian 12 | * 13 | * @date 2006-05-21 14 | * @date 2008-10-29 (added limits) 15 | * @author Kartik Subramanian 16 | */ 17 | 18 | #ifndef _BITS_TYPES_H_ 19 | #define _BITS_TYPES_H_ 20 | 21 | 22 | #ifndef ASSEMBLER 23 | 24 | #define offsetof(type, member) ((size_t)(&(((type *)0)->member))) 25 | 26 | typedef enum bool_e 27 | { 28 | FALSE = 0, 29 | TRUE 30 | } bool_e; 31 | 32 | #define NULL ((void*)0) 33 | 34 | typedef unsigned long size_t; 35 | typedef long ssize_t; 36 | 37 | /* --- Guaranteed length --- */ 38 | 39 | typedef char int8_t; 40 | typedef short int16_t; 41 | typedef int int32_t; 42 | typedef long long int64_t; 43 | 44 | typedef unsigned char uint8_t; 45 | typedef unsigned short uint16_t; 46 | typedef unsigned int uint32_t; 47 | typedef unsigned long long uint64_t; 48 | 49 | /* --- Pointer length --- */ 50 | 51 | typedef int32_t intptr_t; 52 | typedef uint32_t uintptr_t; 53 | 54 | #endif /* ASSEMBLER */ 55 | 56 | /* --- Sizes --- */ 57 | 58 | #define UINT8_MAX 0xff 59 | #define UINT16_MAX 0xffff 60 | #define UINT32_MAX 0xffffffff 61 | #define UINT64_MAX 0xffffffffffffffff 62 | 63 | #define INT8_MAX 0x7f 64 | #define INT16_MAX 0x7fff 65 | #define INT32_MAX 0x7fffffff 66 | #define INT64_MAX 0x7fffffffffffffff 67 | #define INT8_MIN (-INT8_MAX -1) 68 | #define INT16_MIN (-INT16_MAX -1) 69 | #define INT32_MIN (-INT32_MAX -1) 70 | #define INT64_MIN (-INT64_MAX -1) 71 | 72 | #define SIZE_MAX UINT32_MAX 73 | #define SSIZE_MAX INT32_MAX 74 | #define SSIZE_MIN INT32_MIN 75 | 76 | #define CHAR_BIT 8 77 | 78 | #define UCHAR_MAX UINT8_MAX 79 | #define USHRT_MAX UINT16_MAX 80 | #define UINT_MAX UINT32_MAX 81 | #define ULONG_MAX UINT32_MAX 82 | #define ULLONG_MAX UINT64_MAX 83 | 84 | #define SCHAR_MAX INT8_MAX 85 | #define CHAR_MAX SCHAR_MAX 86 | #define SHRT_MAX INT16_MAX 87 | #define INT_MAX INT32_MAX 88 | #define LONG_MAX INT32_MAX 89 | #define LLONG_MAX INT64_MAX 90 | #define SCHAR_MIN INT8_MIN 91 | #define CHAR_MIN SCHAR_MIN 92 | #define SHRT_MIN INT16_MIN 93 | #define INT_MIN INT32_MIN 94 | #define LONG_MIN INT32_MIN 95 | #define LLONG_MIN INT64_MIN 96 | 97 | 98 | #endif /* _BITS_TYPES_H_ */ 99 | -------------------------------------------------------------------------------- /lab4/kernel/kernel.mk: -------------------------------------------------------------------------------- 1 | KERNEL = $(KDIR)/kernel 2 | KSTART = $(KDIR)/start.o 3 | 4 | # All core kernel objects go here. Add objects here if you need to. 5 | KOBJS := assert.o main.o math.o memcheck.o raise.o ctype.o hexdump.o device.o 6 | KOBJS := $(KOBJS:%=$(KDIR)/%) 7 | 8 | -include $(KDIR)/arm/kernel.mk 9 | -include $(KDIR)/syscall/kernel.mk 10 | -include $(KDIR)/sched/kernel.mk 11 | -include $(KDIR)/lock/kernel.mk 12 | 13 | ALL_OBJS += $(KOBJS) $(KSTART) 14 | ALL_CLOBBERS += $(KERNEL) $(KERNEL).bin 15 | 16 | # Put everything needed by the kernel into the final binary. 17 | # KOBJS contains core kernel objects. 18 | # AOBJS contains objects that are ARM dependent. 19 | # UOBJS contains objects that are U-boot dependent. 20 | 21 | $(KERNEL): $(KSTART) $(KOBJS) $(UOBJS) 22 | @echo LD $(notdir $@) 23 | @$(LD) -static $(LDFLAGS) -o $@ $^ $(LIBGCC) 24 | 25 | -------------------------------------------------------------------------------- /lab4/kernel/lock/kernel.mk: -------------------------------------------------------------------------------- 1 | LOCK_OBJS := mutex.o 2 | LOCK_OBJS := $(LOCK_OBJS:%=$(KDIR)/lock/%) 3 | 4 | KOBJS += $(LOCK_OBJS) 5 | -------------------------------------------------------------------------------- /lab4/kernel/lock/mutex.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mutex.c 3 | * 4 | * @brief Implements mutices. 5 | * 6 | * @author Qinyu Tong 7 | * HuaCong Cai 8 | * 9 | * @date Tue Nov 25 15:23:08 EST 2014 10 | */ 11 | 12 | //#define DEBUG_MUTEX 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #ifdef DEBUG_MUTEX 22 | #include // temp 23 | #endif 24 | 25 | mutex_t gtMutex[OS_NUM_MUTEX]; 26 | 27 | void mutex_init() 28 | { 29 | int i; 30 | for (i = 0 ; i < OS_NUM_MUTEX; i++) { 31 | gtMutex[i].bAvailable = TRUE; 32 | gtMutex[i].pHolding_Tcb = NULL; 33 | gtMutex[i].bLock = FALSE; 34 | gtMutex[i].pSleep_queue = NULL; 35 | } 36 | } 37 | 38 | int mutex_create(void) //find the first avaliable mutex, then return. 39 | { 40 | int i; 41 | disable_device_interrupts(); 42 | 43 | for (i = 0 ; i < OS_NUM_MUTEX; i++) { 44 | if (gtMutex[i].bAvailable) { 45 | gtMutex[i].bAvailable = FALSE; 46 | enable_device_interrupts(); 47 | return i; 48 | } 49 | } 50 | 51 | if (i == OS_NUM_MUTEX) { //no availiable mutex, return -ENOMEM to indicate error 52 | enable_device_interrupts(); 53 | return -ENOMEM; 54 | } 55 | return -ENOMEM; 56 | } 57 | 58 | int mutex_lock(int mutex __attribute__((unused))) 59 | { 60 | tcb_t* pSleep_tcb; 61 | tcb_t* cur_tcb; 62 | mutex_t* pMutex; 63 | 64 | disable_device_interrupts(); 65 | 66 | if (mutex < 0 || mutex > OS_NUM_MUTEX - 1) { //invalid mutex id 67 | enable_device_interrupts(); 68 | return -EINVAL; 69 | } 70 | 71 | pMutex = >Mutex[mutex]; //using local variable to avoid unnecessary reference gtMutex[mutex] 72 | 73 | if(pMutex->bAvailable){ // mutex has not been created yet 74 | enable_device_interrupts(); 75 | return -EINVAL; 76 | } 77 | 78 | cur_tcb = get_cur_tcb(); //get current tcb 79 | 80 | if (pMutex->pHolding_Tcb == cur_tcb) {//current task already hold the mutex 81 | enable_device_interrupts(); 82 | return -EDEADLOCK; 83 | } 84 | 85 | if (pMutex->bLock) { //the mutex has been hold by other task 86 | 87 | pSleep_tcb = pMutex->pSleep_queue; 88 | if (pSleep_tcb == NULL) { //sleep queue empty, the tcb became the first node of sleep queue 89 | pMutex->pSleep_queue = cur_tcb; 90 | cur_tcb->sleep_queue = NULL; //Doesn't actually needed, just incase 91 | } 92 | else{ //sleep queue not empty, append cur_tcb to the queue 93 | while (pSleep_tcb->sleep_queue != NULL){ // find the last node in the queue 94 | pSleep_tcb = pSleep_tcb->sleep_queue; 95 | } 96 | 97 | pSleep_tcb->sleep_queue = cur_tcb; 98 | cur_tcb->sleep_queue = NULL; //doesn't actually needed 99 | } 100 | enable_device_interrupts(); 101 | dispatch_sleep(); //can't acquire lock, go to sleep 102 | } 103 | else{ //mutex is free 104 | pMutex->pHolding_Tcb = cur_tcb; 105 | pMutex->bLock = TRUE; 106 | pMutex->pSleep_queue = NULL; 107 | enable_device_interrupts(); 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | int mutex_unlock(int mutex __attribute__((unused))) 114 | { 115 | tcb_t* pSleep_tcb; 116 | tcb_t* cur_tcb; 117 | mutex_t* pMutex; 118 | 119 | disable_device_interrupts(); 120 | cur_tcb = get_cur_tcb(); 121 | 122 | if (mutex < 0 || mutex > OS_NUM_MUTEX - 1) { //invalid mutex id 123 | enable_device_interrupts(); 124 | return -EINVAL; 125 | } 126 | 127 | pMutex = >Mutex[mutex]; //using local variable to avoid unnessary reference gtMutex[mutex] 128 | 129 | if(pMutex->bAvailable){ // mutex has not been created yet 130 | enable_device_interrupts(); 131 | return -EINVAL; 132 | } 133 | 134 | if ( pMutex->pHolding_Tcb != cur_tcb ) {//current task does not hold the mutex 135 | enable_device_interrupts(); 136 | return -EPERM; 137 | } 138 | 139 | if (pMutex->pSleep_queue == NULL) { //no task wait for this mutex, release the lock 140 | pMutex->pHolding_Tcb = NULL; 141 | pMutex->bLock = FALSE; 142 | } 143 | else{ //wake first waiting task, handed over mutex to first waiting task 144 | //remove the first sleep task from queue 145 | pSleep_tcb = pMutex->pSleep_queue; 146 | pMutex->pHolding_Tcb = pSleep_tcb; 147 | pMutex->pSleep_queue = pSleep_tcb->sleep_queue; //Mutex's sleep queue point to next sleep task; 148 | pSleep_tcb->sleep_queue = NULL; //clear sleep queue of the first waiting task 149 | 150 | runqueue_add(pSleep_tcb,pSleep_tcb->cur_prio); 151 | } 152 | 153 | enable_device_interrupts(); 154 | 155 | dispatch_save(); //maybe the waiting task has the highest priority 156 | 157 | return 0; 158 | } 159 | 160 | -------------------------------------------------------------------------------- /lab4/kernel/main.c: -------------------------------------------------------------------------------- 1 | /** @file main.c 2 | * 3 | * @brief kernel main 4 | * 5 | * @author Huacong Cai 6 | * @author Qinyu Tong 7 | * 8 | * @date 2014-11-24 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | uint32_t global_data; 19 | volatile unsigned tick_counter; 20 | uint32_t old_sp; //save kernel's sp 21 | 22 | int kmain(int argc __attribute__((unused)), char** argv __attribute__((unused)), uint32_t table) 23 | { 24 | int ret; 25 | 26 | //app_startup(); 27 | 28 | //save uboot api table 29 | global_data = table; 30 | 31 | //initialize 32 | init_swi(); 33 | init_interrupt(); 34 | init_timer(); 35 | mutex_init(); 36 | dev_init(); 37 | 38 | //run user program 39 | ret = enter_user_mode(argc, argv); 40 | 41 | //restore 42 | destroy_swi(); 43 | destroy_interrupt(); 44 | destroy_timer(); 45 | 46 | return ret; 47 | 48 | assert(0); /* should never get here */ 49 | } 50 | -------------------------------------------------------------------------------- /lab4/kernel/math.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file math.c 3 | * 4 | * @brief Contains integer math routines. 5 | * 6 | * This file should contain both optimized and unoptimized versions of a 7 | * routine. NDEBUG is used to switch between them. 8 | * 9 | * @author Kartik Subramanian 10 | * @date 2008-08-07 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | /** 17 | * @brief Folds the sum function over a region. 18 | * 19 | * This function pretends that the given input is an array of integers. This 20 | * function can be used as a poor man's integrity checker. 21 | * 22 | * @param buf The start of the buffer. 23 | * @param size The number of integers in the region. 24 | */ 25 | unsigned int sum_region(unsigned int* buf, size_t num_words) 26 | { 27 | size_t i; 28 | unsigned int result; 29 | 30 | result = 0; 31 | for (i = 0; i != num_words; i++) 32 | result += buf[i]; 33 | 34 | return result; 35 | } 36 | 37 | 38 | #ifndef NDEBUG 39 | /* Debug implementations */ 40 | 41 | /** 42 | * @brief Finds the highest set bit in an integer. 43 | * 44 | * The integer log base 2 is equivalent to finding the bit number of the highest 45 | * set bit (counting from 0). 46 | * 47 | * @warning This method will return 0 if 0 is provided as the argument. 48 | * 49 | * @return log2(x) 50 | * @param x The unsigned number to take the logarithm of. 51 | */ 52 | unsigned int ilog2(unsigned int x) 53 | { 54 | unsigned int r = 0; 55 | 56 | while (x >>= 1) 57 | r++; 58 | 59 | return r; 60 | } 61 | 62 | #else /* NDEBUG */ 63 | /* Optimized implementations */ 64 | 65 | /** 66 | * @brief Finds the highest set bit in an integer. 67 | * 68 | * The integer log base 2 is equivalent to finding the bit number of the highest 69 | * set bit (counting from 0). 70 | * 71 | * This code was taken from public domain code base of: 72 | * Sean Eron Anderson 73 | * seander@cs.stanford.edu 74 | * http://graphics.stanford.edu/~seander/bithacks.html 75 | * 76 | * @warning ASSUMES 32-BIT INTEGERS! Fix this code on an architecture port. 77 | * @warning This method will return 0 if 0 is provided as the argument. 78 | * 79 | * @return log2(x) 80 | * @param x The unsigned number to take the logarithm of. 81 | */ 82 | unsigned int ilog2(unsigned int v) 83 | { 84 | const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; 85 | const unsigned int S[] = {1, 2, 4, 8, 16}; 86 | int i; 87 | 88 | unsigned int r = 0; 89 | for (i = sizeof(b)/sizeof(b[0]) - 1; i >= 0; i--) 90 | { 91 | if (v & b[i]) 92 | { 93 | v >>= S[i]; 94 | r |= S[i]; 95 | } 96 | } 97 | 98 | return r; 99 | } 100 | 101 | #endif /* NDEBUG */ 102 | -------------------------------------------------------------------------------- /lab4/kernel/memcheck.c: -------------------------------------------------------------------------------- 1 | /** @file memcheck.c 2 | * 3 | * @brief Memory address validation. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-21 7 | */ 8 | 9 | #include "kernel.h" 10 | 11 | /** 12 | * @brief This function verifies of a given buffer is within an address range. 13 | * 14 | * @param start A pointer to the start of the buffer. 15 | * @param count The number of bytes in the buffer. 16 | * @param base The base of the address space checked against. 17 | * @param bound The bound or limit of the address space checked against. 18 | * This is the address of the word past the last valid address in 19 | * the segment. 20 | * 21 | * @return 0 Address is invalid. 22 | * @return 1 Address is valid. 23 | */ 24 | int valid_addr(const void* start, size_t count, uintptr_t base, uintptr_t bound) 25 | { 26 | uintptr_t mem_start = (uintptr_t)start; 27 | uintptr_t mem_end = (uintptr_t)start + count; 28 | 29 | if (mem_start < base || mem_start >= bound) 30 | return 0; 31 | 32 | if (mem_end < mem_start || mem_end > bound) 33 | return 0; 34 | 35 | return 1; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /lab4/kernel/raise.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file raise.c 3 | * 4 | * @brief Divide by zero exception handler. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #include 10 | 11 | void raise(void) 12 | { 13 | puts("Divide by zero -- In kernel\n"); 14 | 15 | while(1); 16 | } 17 | -------------------------------------------------------------------------------- /lab4/kernel/sched/ctx_switch.c: -------------------------------------------------------------------------------- 1 | /** @file ctx_switch.c 2 | * 3 | * @brief C wrappers around assembly context switch routines. 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include "sched_i.h" 19 | 20 | #ifdef DEBUG_MUTEX 21 | #include 22 | #endif 23 | 24 | static __attribute__((unused)) tcb_t* cur_tcb; /* use this if needed */ 25 | 26 | /** 27 | * @brief Initialize the current TCB and priority. 28 | * 29 | * Set the initialization thread's priority to IDLE so that anything 30 | * will preempt it when dispatching the first task. 31 | */ 32 | void dispatch_init(tcb_t* idle __attribute__((unused))) 33 | { 34 | disable_device_interrupts(); 35 | cur_tcb = idle; 36 | enable_device_interrupts(); 37 | } 38 | 39 | 40 | /** 41 | * @brief Context switch to the highest priority task while saving off the 42 | * current task state. 43 | * 44 | * This function needs to be externally synchronized. 45 | * We could be switching from the idle task. The priority searcher has been tuned 46 | * to return IDLE_PRIO for a completely empty run_queue case. 47 | */ 48 | void dispatch_save(void) 49 | { 50 | tcb_t* targ_tcb; 51 | sched_context_t* cur_ctx; 52 | sched_context_t* targ_ctx; 53 | 54 | disable_device_interrupts(); //before modify kernel data structure, disable interrupt, becasue kernel is preemptive 55 | 56 | runqueue_add(cur_tcb, cur_tcb->cur_prio); //add current task to run queue 57 | targ_tcb = runqueue_remove(highest_prio()); //get the highest priority task in run queue 58 | 59 | if (targ_tcb == cur_tcb){ //if target task already is current task, don't need to change context 60 | enable_device_interrupts(); 61 | return; 62 | } 63 | 64 | cur_ctx = &(cur_tcb->context); //get current context 65 | targ_ctx = &(targ_tcb->context); //get target context address 66 | 67 | cur_tcb = targ_tcb; //change cur_tcb to targ_tcb 68 | 69 | enable_device_interrupts(); 70 | 71 | ctx_switch_full(targ_ctx, cur_ctx); //context switch from current to target 72 | 73 | //enable_device_interrupts(); // this enable is executed by newly runned target task 74 | } 75 | 76 | /** 77 | * @brief Context switch to the highest priority task that is not this task -- 78 | * don't save the current task state. 79 | * 80 | * There is always an idle task to switch to. 81 | */ 82 | void dispatch_nosave(void) 83 | { 84 | tcb_t* targ_tcb; 85 | sched_context_t* targ_ctx; 86 | 87 | disable_device_interrupts(); 88 | 89 | targ_tcb = runqueue_remove(highest_prio()); //get the highest priority task in run queue 90 | targ_ctx = &(targ_tcb->context); //get target context address 91 | cur_tcb = targ_tcb; 92 | 93 | enable_device_interrupts(); 94 | 95 | ctx_switch_half(targ_ctx); 96 | 97 | //enable_device_interrupts(); 98 | 99 | } 100 | 101 | 102 | /** 103 | * @brief Context switch to the highest priority task that is not this task -- 104 | * and save the current task but don't mark is runnable. 105 | * 106 | * There is always an idle task to switch to. 107 | */ 108 | void dispatch_sleep(void) 109 | { 110 | tcb_t* targ_tcb; 111 | sched_context_t* cur_ctx; 112 | sched_context_t* targ_ctx; 113 | 114 | disable_device_interrupts(); 115 | 116 | targ_tcb = runqueue_remove(highest_prio()); //get the highest priority task in run queue 117 | 118 | targ_ctx = &(targ_tcb->context); //get target context address 119 | cur_ctx = &(cur_tcb->context); //get current context 120 | 121 | 122 | cur_tcb = targ_tcb; //change cur_tcb to targ_tcb 123 | 124 | enable_device_interrupts(); 125 | 126 | ctx_switch_full(targ_ctx, cur_ctx); //context switch from current to target 127 | //enable_device_interrupts(); 128 | } 129 | 130 | /** 131 | * @brief Returns the priority value of the current task. 132 | */ 133 | uint8_t get_cur_prio(void) 134 | { 135 | return cur_tcb->cur_prio; 136 | } 137 | 138 | /** 139 | * @brief Returns the TCB of the current task. 140 | */ 141 | tcb_t* get_cur_tcb(void) 142 | { 143 | return cur_tcb; 144 | } 145 | -------------------------------------------------------------------------------- /lab4/kernel/sched/ctx_switch_asm.S: -------------------------------------------------------------------------------- 1 | /** @file ctx_switch_asm.S 2 | * 3 | * @brief Contains the core context switch routine. 4 | * 5 | * These routines all assume that the caller is following AAPCS, needs 6 | * no co-processor registers and that the caller is in SVC mode. Furthermore, 7 | * the SPSR is considered a spare/scratch register and hence, is not saved. 8 | * 9 | *@author Qinyu Tong 10 | * HuaCong Cai 11 | * 12 | * @date Tue Nov 25 15:23:08 EST 2014 13 | */ 14 | 15 | .file "ctx_switch_asm.S" 16 | 17 | #include 18 | #include 19 | 20 | /** 21 | * @brief Special exit routine from the scheduler that launches a task for the 22 | * first time. 23 | * 24 | * r4 contains the user entry point. 25 | * r5 contains the single argument to the user function called. 26 | * r6 contains the user-mode stack pointer. 27 | * Upon completion, we should be in user mode. 28 | */ 29 | FUNC(launch_task) 30 | mov r0, r5 31 | mov r1, #0 32 | mov r2, #0 33 | mov r3, #0 34 | mov r5, #0 35 | mov r8, #0 36 | mov ip, #0 37 | msr cpsr_c, #(PSR_MODE_USR) 38 | mov sp, r6 39 | mov r6, #0 40 | ldr lr, =0xdeadbeef /* Causes a crash instead of calling the reset vector */ 41 | mov pc, r4 42 | 43 | /* r0 points to the target context, r1 to the current context. */ 44 | /* add your code to perform a full context switch */ 45 | FUNC(ctx_switch_full) 46 | stmia r1, {r4-r11, sp, lr} /* save current task's context */ 47 | ldmia r0, {r4-r11, sp, lr} /* load target task's context */ 48 | mov pc, lr 49 | 50 | /*add your code to perform a half context switch */ 51 | FUNC(ctx_switch_half) 52 | ldmia r0, {r4-r11, sp, lr} /* load target task's context */ 53 | mov pc, lr 54 | 55 | -------------------------------------------------------------------------------- /lab4/kernel/sched/kernel.mk: -------------------------------------------------------------------------------- 1 | SCHED_OBJS := sched.o ub_test.o ctx_switch.o ctx_switch_asm.o run_queue.o 2 | SCHED_OBJS := $(SCHED_OBJS:%=$(KDIR)/sched/%) 3 | 4 | KOBJS += $(SCHED_OBJS) 5 | -------------------------------------------------------------------------------- /lab4/kernel/sched/run_queue.c: -------------------------------------------------------------------------------- 1 | /** @file run_queue.c 2 | * 3 | * @brief Run queue maintainence routines. 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include "sched_i.h" 17 | #include 18 | 19 | 20 | 21 | static tcb_t* run_list[OS_MAX_TASKS] __attribute__((unused)); 22 | 23 | /* A high bit in this bitmap means that the task whose priority is 24 | * equal to the bit number of the high bit is runnable. 25 | */ 26 | static uint8_t run_bits[OS_MAX_TASKS/8] __attribute__((unused)); 27 | 28 | /* This is a trie structure. Tasks are grouped in groups of 8. If any task 29 | * in a particular group is runnable, the corresponding group flag is set. 30 | * Since we can only have 64 possible tasks, a single byte can represent the 31 | * run bits of all 8 groups. 32 | */ 33 | static uint8_t group_run_bits __attribute__((unused)); 34 | 35 | /* This unmap table finds the bit position of the lowest bit in a given byte 36 | * Useful for doing reverse lookup. 37 | */ 38 | static uint8_t prio_unmap_table[] __attribute__((unused)) = 39 | { 40 | 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 41 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 42 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 43 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 44 | 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 45 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 46 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 47 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 48 | 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 49 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 50 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 51 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 52 | 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 53 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 54 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 55 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 56 | }; 57 | 58 | /** 59 | * @brief Clears the run-queues and sets them all to empty. 60 | */ 61 | void runqueue_init(void) 62 | { 63 | int i = OS_MAX_TASKS - 1; 64 | while (i >= 0 ) { 65 | run_list[i] = NULL; //set run queue to empty 66 | i--; 67 | } 68 | 69 | //set run bits and group run bits to 0 70 | i = OS_MAX_TASKS/8 - 1; 71 | while (i >= 0 ) { 72 | run_bits[i] = 0; 73 | i--; 74 | } 75 | 76 | group_run_bits = 0; 77 | 78 | } 79 | 80 | /** 81 | * @brief Adds the thread identified by the given TCB to the runqueue at 82 | * a given priority. 83 | * 84 | * The native priority of the thread need not be the specified priority. The 85 | * only requirement is that the run queue for that priority is empty. This 86 | * function needs to be externally synchronized. 87 | */ 88 | void runqueue_add(tcb_t* tcb __attribute__((unused)), uint8_t prio __attribute__((unused))) 89 | { 90 | uint8_t group,pos_in_group; 91 | 92 | group = prio>>3; 93 | pos_in_group = prio&0x07; 94 | 95 | run_list[prio] = tcb; 96 | group_run_bits = group_run_bits|(0x1 << group); 97 | run_bits[group] = run_bits[group]|(0x1 << pos_in_group); 98 | } 99 | 100 | 101 | /** 102 | * @brief Empty the run queue of the given priority. 103 | * 104 | * @return The tcb at enqueued at the given priority. 105 | * 106 | * This function needs to be externally synchronized. 107 | */ 108 | tcb_t* runqueue_remove(uint8_t prio __attribute__((unused))) 109 | { 110 | tcb_t* rm_tcb = run_list[prio]; 111 | uint8_t group,pos_in_group; 112 | 113 | group = prio>>3; 114 | pos_in_group = prio&0x07; 115 | 116 | run_bits[group] = run_bits[group]&(~(0x1 << pos_in_group)); //clear corresponding run bit 117 | 118 | if (run_bits[group] == 0) { //if no task is ready to run in this priority group 119 | group_run_bits = group_run_bits&(~(0x1 << group)); 120 | } 121 | 122 | run_list[prio] = NULL; 123 | 124 | return rm_tcb; 125 | } 126 | 127 | /** 128 | * @brief This function examines the run bits and the run queue and returns the 129 | * priority of the runnable task with the highest priority (lower number). 130 | */ 131 | uint8_t highest_prio(void) 132 | { 133 | uint8_t x,y,prio; 134 | y = prio_unmap_table[group_run_bits]; 135 | x = prio_unmap_table[run_bits[y]]; 136 | prio = (y<<3) + x; 137 | return prio; 138 | } 139 | -------------------------------------------------------------------------------- /lab4/kernel/sched/sched.c: -------------------------------------------------------------------------------- 1 | /** @file sched.c 2 | * 3 | * @brief Top level implementation of the scheduler. 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include "sched_i.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | tcb_t system_tcb[OS_MAX_TASKS]; /*allocate memory for system TCBs */ 26 | 27 | void sched_init(task_t* main_task __attribute__((unused))) 28 | { 29 | dispatch_nosave(); 30 | } 31 | 32 | /** 33 | * @brief This is the idle task that the system runs when no other task is runnable 34 | */ 35 | 36 | static void __attribute__((unused)) idle(void) 37 | { 38 | enable_interrupts(); 39 | while(1); 40 | } 41 | 42 | /** 43 | * @brief Allocate user-stacks and initializes the kernel contexts of the 44 | * given threads. 45 | * 46 | * This function assumes that: 47 | * - num_tasks < number of tasks allowed on the system. 48 | * - the tasks have already been deemed schedulable and have been appropriately 49 | * scheduled. In particular, this means that the task list is sorted in order 50 | * of priority -- higher priority tasks come first. 51 | * 52 | * @param tasks A list of scheduled task descriptors. 53 | * @param size The number of tasks is the list. 54 | */ 55 | void allocate_tasks(task_t** tasks __attribute__((unused)), size_t num_tasks __attribute__((unused))) 56 | { 57 | unsigned i; 58 | disable_device_interrupts(); 59 | 60 | runqueue_init(); 61 | 62 | for (i = 1; i <= num_tasks; i++){ //i=0 reserve for the special priority task 63 | system_tcb[i].native_prio = i; 64 | system_tcb[i].cur_prio = i; 65 | system_tcb[i].context.r4 = (uint32_t)(*tasks)[i-1].lambda; //task entry point 66 | system_tcb[i].context.r5 = (uint32_t)(*tasks)[i-1].data; 67 | system_tcb[i].context.r6 = (uint32_t)(*tasks)[i-1].stack_pos; //user_mode stack 68 | system_tcb[i].context.r8 = global_data; 69 | system_tcb[i].context.sp = (void *)system_tcb[i].kstack_high; //swi supervisor mode stack 70 | system_tcb[i].context.lr = (void *)launch_task; 71 | 72 | system_tcb[i].holds_lock = 0; 73 | system_tcb[i].sleep_queue = NULL; 74 | 75 | runqueue_add(&(system_tcb[i]), i); //add to run queue 76 | } 77 | //allocate idle task 78 | system_tcb[IDLE_PRIO].native_prio = IDLE_PRIO; 79 | system_tcb[IDLE_PRIO].cur_prio = IDLE_PRIO; 80 | 81 | system_tcb[IDLE_PRIO].context.r4 = (uint32_t)idle; //task entry point 82 | system_tcb[IDLE_PRIO].context.r5 = 0; 83 | system_tcb[IDLE_PRIO].context.r6 = (uint32_t)system_tcb[IDLE_PRIO].kstack_high; 84 | system_tcb[IDLE_PRIO].context.r8 = global_data; 85 | system_tcb[IDLE_PRIO].context.sp = (void *)system_tcb[IDLE_PRIO].kstack_high; 86 | system_tcb[IDLE_PRIO].context.lr = (void *)launch_task; 87 | 88 | system_tcb[IDLE_PRIO].holds_lock = 0; 89 | system_tcb[IDLE_PRIO].sleep_queue = NULL; 90 | 91 | runqueue_add(&(system_tcb[IDLE_PRIO]), IDLE_PRIO); 92 | 93 | enable_device_interrupts(); 94 | } 95 | 96 | -------------------------------------------------------------------------------- /lab4/kernel/sched/sched_i.h: -------------------------------------------------------------------------------- 1 | /** @file sched_i.h 2 | * 3 | * @brief Internal header -- runqueue and tcb maintainence routines. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-21 7 | */ 8 | 9 | #ifndef _SCHED_I_H_ 10 | #define _SCHED_I_H_ 11 | 12 | #include 13 | 14 | 15 | void dispatch_init(tcb_t* idle); 16 | void runqueue_init(void); 17 | 18 | void ctx_switch_full(volatile void* next_ctx, volatile void* cur_ctx); 19 | void ctx_switch_half(volatile void* next_ctx) __attribute__((noreturn)); 20 | 21 | /** A list of every TCB+kernel stack that can exist on this system. 22 | * Note -- this list is not ordered by anything. 23 | */ 24 | extern tcb_t system_tcb[OS_MAX_TASKS]; 25 | 26 | #endif /* _SCHED_I_H_ */ 27 | -------------------------------------------------------------------------------- /lab4/kernel/sched/ub_test.c: -------------------------------------------------------------------------------- 1 | /** @file ub_test.c 2 | * 3 | * @brief The UB Test for basic schedulability 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-20 7 | */ 8 | 9 | //#define DEBUG 0 10 | 11 | #include 12 | #ifdef DEBUG 13 | #include 14 | #endif 15 | 16 | 17 | /** 18 | * @brief Perform UB Test and reorder the task list. 19 | * 20 | * The task list at the end of this method will be sorted in order is priority 21 | * -- from highest priority (lowest priority number) to lowest priority 22 | * (highest priority number). 23 | * 24 | * @param tasks An array of task pointers containing the task set to schedule. 25 | * @param num_tasks The number of tasks in the array. 26 | * 27 | * @return 0 The test failed. 28 | * @return 1 Test succeeded. The tasks are now in order. 29 | */ 30 | int assign_schedule(task_t** tasks __attribute__((unused)), size_t num_tasks __attribute__((unused))) 31 | { 32 | 33 | return 1; // fix this; dummy return to prevent compiler warnings 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab4/kernel/start.S: -------------------------------------------------------------------------------- 1 | /** 2 | * @file start.S 3 | * 4 | * @brief Kernel startup routine 5 | * 6 | * @author Mike Kasick 7 | * @date Tue, 23 Oct 2007 11:20:33 -0400 8 | * 9 | * @author Kartik Subramanian 10 | * @date 2008-07-06 11 | */ 12 | 13 | #include 14 | 15 | .file "start.S" 16 | 17 | FUNC(_start) 18 | /* 19 | * Branch immediately to main without altering the execution environment. 20 | * This indirection is needed to guarantee that the program entry point is 21 | * LOAD_ADDR (probably 0xa3000000) without placing strict 22 | * requirements on the layout of kernel.c. Bit first, provide main with the 23 | * jump table address as one of its arguments. 24 | */ 25 | mov r2, r8 26 | b kmain 27 | 28 | -------------------------------------------------------------------------------- /lab4/kernel/syscall/io.c: -------------------------------------------------------------------------------- 1 | /** @file io.c 2 | * 3 | * @brief Kernel I/O syscall implementations 4 | * 5 | * @author Huacong Cai 6 | * @author Qinyu Tong 7 | * @date 2014-11-24 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define EOT_CHAR 0x04 19 | #define DEL_CHAR 0x7f 20 | 21 | 22 | /* Read count bytes (or less) from fd into the buffer buf. */ 23 | ssize_t read_syscall(int fd __attribute__((unused)), char *buf __attribute__((unused)), size_t count __attribute__((unused))) 24 | { 25 | char tempCh; 26 | unsigned length = 0; 27 | unsigned start = (unsigned int)buf; 28 | unsigned end = (unsigned int)(buf+count); 29 | 30 | //file descriptor is not stdin 31 | if (fd != STDIN_FILENO) 32 | return -EBADF; 33 | 34 | //memory range not exceeds SDRAM 35 | if (start >= 0xa0000000 && end <= 0xa3ffffff) 36 | { 37 | while (length < count) 38 | { 39 | tempCh = getc(); 40 | 41 | if(tempCh == 4) //EOT, echo to stdout and return length 42 | return length; 43 | else if(tempCh == 8 || tempCh == 127) //Backspace or delete, echo "\b \b" 44 | { 45 | if (length > 0) { 46 | length -= 1; 47 | buf[length] = '\0'; 48 | } 49 | puts("\b \b"); 50 | } 51 | else if(tempCh == 10 || tempCh == 13) // new line or carriage return, newline in buffer, echo and retun 52 | { 53 | buf[length] = '\n'; 54 | putc('\n'); 55 | length += 1; 56 | return length; 57 | } 58 | else 59 | { 60 | buf[length] = tempCh; 61 | putc(tempCh); 62 | length += 1; 63 | } 64 | } 65 | } 66 | else 67 | return -EFAULT; 68 | 69 | return length; 70 | } 71 | 72 | /* Write count bytes to fd from the buffer buf. */ 73 | ssize_t write_syscall(int fd __attribute__((unused)), const char *buf __attribute__((unused)), size_t count __attribute__((unused))) 74 | { 75 | unsigned i; 76 | unsigned start = (unsigned int)buf; 77 | unsigned end = (unsigned int)(buf+count); 78 | 79 | //file descriptor is not stdout 80 | if (fd != STDOUT_FILENO) 81 | return -EBADF; 82 | 83 | //memory range not exceeds ROM or SDRAM 84 | if ( end <= 0x00ffffff || 85 | (start >= 0xa0000000 && end <= 0xa3ffffff)) 86 | { 87 | for(i=0; i 6 | * @author Qinyu Tong 7 | * @date 2014-11-24 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /** 24 | * @ task create takes a set of tasks, verifies that they are schedulable, 25 | * and then begins to schedule them. 26 | * @ Argument tasks: An array of task descriptors that qualify the tasks to create 27 | * Argument num_tasks: The number of elements in the array. 28 | * @ return value: Upon success, this function does not return, error number returned 29 | * when failed. 30 | **/ 31 | int task_create(task_t* tasks __attribute__((unused)), size_t num_tasks __attribute__((unused))) 32 | { 33 | task_t tmp_tcb; 34 | unsigned int i, j; 35 | if (num_tasks > OS_MAX_TASKS) { 36 | return -EINVAL; 37 | } 38 | 39 | if (!valid_addr(tasks, num_tasks, USR_START_ADDR, USR_END_ADDR)) { 40 | return -EFAULT; 41 | } 42 | 43 | for (i = 0; i< num_tasks; i++) { 44 | if (tasks[i].C > tasks[i].T) { 45 | return -ESCHED; 46 | } 47 | } 48 | 49 | /*sort tasks*/ 50 | for (i = 0; i < num_tasks; i++) { 51 | for (j = i+1; j < num_tasks; j++) { 52 | if (tasks[i].T > tasks[j].T) { 53 | tmp_tcb = tasks[i]; 54 | tasks[i] = tasks[j]; 55 | tasks[j] = tmp_tcb; 56 | } 57 | } 58 | } 59 | 60 | dev_clear(); //clear old device sleep queue 61 | allocate_tasks(&tasks,num_tasks); 62 | sched_init(NULL); 63 | return 0; //to avoid warning 64 | } 65 | 66 | /** 67 | * @ wait next event is singnalled for the device 68 | * @ param dev Device number. A valid device number – 0, 1, 2 or 3. 69 | * @ returnReturn int 70 | * A zero is returned upon the successful acquisition of the mutex. Upon failure, 71 | *an error code may be returned. 72 | * EINVAL The provided device identifier is invalid. 73 | */ 74 | int event_wait(unsigned int dev __attribute__((unused))) 75 | { 76 | if (dev > NUM_DEVICES - 1) { // invalid device number 77 | return -EINVAL; 78 | } 79 | 80 | dev_wait(dev); 81 | return 0; 82 | } 83 | 84 | 85 | /* An invalid syscall causes the kernel to exit. */ 86 | void invalid_syscall(unsigned int call_num __attribute__((unused))) 87 | { 88 | printf("Kernel panic: invalid syscall -- 0x%08x\n", call_num); 89 | 90 | disable_interrupts(); 91 | while(1); 92 | } 93 | -------------------------------------------------------------------------------- /lab4/kernel/syscall/time.c: -------------------------------------------------------------------------------- 1 | /** @file time.c 2 | * 3 | * @brief Kernel timer based syscall implementations 4 | * 5 | * @author Huacong Cai 6 | * @author Qinyu Tong 7 | * @date 2014-11-24 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | extern volatile unsigned tick_counter; 18 | 19 | unsigned long time_syscall(void) 20 | { 21 | //since return system time is unsigned, the max value is 4,294,967,295 22 | //the return value will overflow if the system run continuously 16 months 23 | return tick_counter * OS_TIMER_RESOLUTION; 24 | } 25 | 26 | 27 | 28 | /** 29 | * @brief Waits in a tight loop for atleast the given number of milliseconds. 30 | * 31 | * @param millis The number of milliseconds to sleep. 32 | * 33 | */ 34 | void sleep_syscall(unsigned long millis __attribute__((unused))) 35 | { 36 | //end_tick is round up 37 | unsigned end_tick; 38 | 39 | if (millis != 0) 40 | end_tick = tick_counter + ((millis-1)/OS_TIMER_RESOLUTION + 1); 41 | else 42 | return; 43 | 44 | while (tick_counter < end_tick); 45 | } 46 | -------------------------------------------------------------------------------- /lab4/mount.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | echo "making" 3 | make 4 | echo "mounting mmc1" 5 | mount /mnt/mmc1 6 | cp kernel/kernel.bin /mnt/mmc1 7 | cp tasks/bin/*.bin /mnt/mmc1 8 | umount /mnt/mmc1 9 | echo "done mounting" 10 | -------------------------------------------------------------------------------- /lab4/tasks/cyclone/cyclone.c: -------------------------------------------------------------------------------- 1 | /** @file cyclone.c 2 | * 3 | * @brief recursively calls task create 4 | * Tests: 1. task_create cancels current task 5 | * 2. Timer has at least 10ms granularity 6 | * 3. Sleep works properly 7 | * @note Dont think this is realted to the OS cyclone 8 | * 9 | * @author Tao Yang(taoy) 10 | * @date 2010-11-30 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | //#include 17 | 18 | #define ITE 30 19 | volatile int ct; 20 | void panic(const char* str) 21 | { 22 | puts(str); 23 | while(1); 24 | } 25 | 26 | void fun1(void* str) 27 | { 28 | ct++; 29 | str = str; 30 | if(ct > ITE) { 31 | puts("Test ends!!"); 32 | while(1) { 33 | ct++; 34 | } 35 | } 36 | sleep(ct * 10); 37 | printf("Time now is %lu\n",time()); 38 | 39 | task_t tasks[1]; 40 | tasks[0].lambda = fun1; 41 | tasks[0].data = (void*)0; 42 | tasks[0].stack_pos = (void*)0xa1000000; 43 | tasks[0].C = 1; 44 | tasks[0].T = PERIOD_DEV3; 45 | 46 | task_create(tasks, 1); 47 | // task create wipe out the task, therefore never reaches here 48 | puts("TASK SHOULD NEVER REACH HERE, FAIL XXXXXXXXXXXXXXXXX"); 49 | } 50 | 51 | 52 | int main(int argc, char** argv) 53 | { 54 | ct = 0; 55 | puts("Test begin"); 56 | task_t tasks[1]; 57 | tasks[0].lambda = fun1; 58 | tasks[0].data = (void*)0; 59 | tasks[0].stack_pos = (void*)0xa1000000; 60 | tasks[0].C = 1; 61 | tasks[0].T = PERIOD_DEV3; 62 | 63 | task_create(tasks, 1); 64 | 65 | puts("WTF!\n"); 66 | argc = argc; 67 | argv = argv; 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /lab4/tasks/cyclone/pack.mk: -------------------------------------------------------------------------------- 1 | PROGS_DAGGER_OBJS := cyclone.o 2 | PROGS_DAGGER_OBJS := $(PROGS_DAGGER_OBJS:%=$(TDIR)/cyclone/%) 3 | ALL_OBJS += $(PROGS_DAGGER_OBJS) 4 | 5 | $(TDIR)/bin/cyclone : $(TSTART) $(PROGS_DAGGER_OBJS) $(TLIBC) 6 | 7 | -------------------------------------------------------------------------------- /lab4/tasks/dagger/dagger.c: -------------------------------------------------------------------------------- 1 | /** @file dagger.c 2 | * 3 | * @brief Creates two simple periodic tasks. 4 | * 5 | * @note This is like knife -- but smaller :) 6 | * 7 | * @author Kartik Subramanian 8 | * @date 2008-11-30 9 | */ 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | void panic(const char* str) 16 | { 17 | puts(str); 18 | while(1); 19 | } 20 | 21 | void fun1(void* str) 22 | { 23 | while(1) 24 | { 25 | putchar((int)str); 26 | if (event_wait(0) < 0) 27 | panic("Dev 0 failed"); 28 | } 29 | } 30 | 31 | void fun2(void* str) 32 | { 33 | while(1) 34 | { 35 | putchar((int)str); 36 | if (event_wait(1) < 0) 37 | panic("Dev 1 failed"); 38 | } 39 | } 40 | 41 | int main(int argc, char** argv) 42 | { 43 | task_t tasks[2]; 44 | tasks[0].lambda = fun1; 45 | tasks[0].data = (void*)'@'; 46 | tasks[0].stack_pos = (void*)0xa2000000; 47 | tasks[0].C = 1; 48 | tasks[0].T = PERIOD_DEV0; 49 | tasks[1].lambda = fun2; 50 | tasks[1].data = (void*)'<'; 51 | tasks[1].stack_pos = (void*)0xa1000000; 52 | tasks[1].C = 1; 53 | tasks[1].T = PERIOD_DEV1; 54 | 55 | task_create(tasks, 2); 56 | argc=argc; /* remove compiler warning */ 57 | argv=argv; /* remove compiler warning */ 58 | 59 | puts("Elvis could not leave the building, but why did your code get here!\n"); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /lab4/tasks/dagger/dagger.dep: -------------------------------------------------------------------------------- 1 | /home/vally/Downloads/lab4/tasks/dagger/dagger.o: \ 2 | /home/vally/Downloads/lab4/tasks/dagger/dagger.c \ 3 | /home/vally/Downloads/lab4/tasks/libc/include/stdio.h \ 4 | /home/vally/Downloads/lab4/tasks/libc/include/stdarg.h \ 5 | /home/vally/Downloads/lab4/tasks/libc/include/sys/types.h \ 6 | /home/vally/Downloads/lab4/tasks/libc/include/bits/types.h \ 7 | /home/vally/Downloads/lab4/tasks/libc/include/task.h \ 8 | /home/vally/Downloads/lab4/tasks/libc/include/unistd.h \ 9 | /home/vally/Downloads/lab4/tasks/libc/include/bits/fileno.h 10 | 11 | /home/vally/Downloads/lab4/tasks/libc/include/stdio.h: 12 | 13 | /home/vally/Downloads/lab4/tasks/libc/include/stdarg.h: 14 | 15 | /home/vally/Downloads/lab4/tasks/libc/include/sys/types.h: 16 | 17 | /home/vally/Downloads/lab4/tasks/libc/include/bits/types.h: 18 | 19 | /home/vally/Downloads/lab4/tasks/libc/include/task.h: 20 | 21 | /home/vally/Downloads/lab4/tasks/libc/include/unistd.h: 22 | 23 | /home/vally/Downloads/lab4/tasks/libc/include/bits/fileno.h: 24 | -------------------------------------------------------------------------------- /lab4/tasks/dagger/pack.mk: -------------------------------------------------------------------------------- 1 | PROGS_DAGGER_OBJS := dagger.o 2 | PROGS_DAGGER_OBJS := $(PROGS_DAGGER_OBJS:%=$(TDIR)/dagger/%) 3 | ALL_OBJS += $(PROGS_DAGGER_OBJS) 4 | 5 | $(TDIR)/bin/dagger : $(TSTART) $(PROGS_DAGGER_OBJS) $(TLIBC) 6 | 7 | -------------------------------------------------------------------------------- /lab4/tasks/hello/hello.c: -------------------------------------------------------------------------------- 1 | /** @file hello.c 2 | * 3 | * @brief Prints out Hello world using the syscall interface. 4 | * 5 | * Links to libc. 6 | * 7 | * @author Kartik Subramanian 8 | * @date 2008-10-29 9 | */ 10 | #include 11 | #include 12 | #include 13 | 14 | const char hello[] = "Hello World\r\n"; 15 | 16 | int main(int argc, char** argv) 17 | { 18 | task_t tasks[2]; 19 | task_create(tasks, 0); 20 | argc=argc; /* remove compiler warning */ 21 | argv[0]=argv[0]; /* remove compiler warning */ 22 | 23 | //puts("Why did your code get here!\n"); 24 | 25 | write(STDOUT_FILENO, hello, sizeof(hello) - 1); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /lab4/tasks/hello/pack.mk: -------------------------------------------------------------------------------- 1 | PROGS_HELLO_OBJS := hello.o 2 | PROGS_HELLO_OBJS := $(PROGS_HELLO_OBJS:%=$(TDIR)/hello/%) 3 | ALL_OBJS += $(PROGS_HELLO_OBJS) 4 | 5 | $(TDIR)/bin/hello : $(TSTART) $(PROGS_HELLO_OBJS) $(TLIBC) 6 | 7 | -------------------------------------------------------------------------------- /lab4/tasks/libc/crt0.S: -------------------------------------------------------------------------------- 1 | /** @file crt0.S 2 | * 3 | * @brief Execution startup routine 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:51:29 -0400 7 | */ 8 | 9 | #include 10 | 11 | .file "crt0.S" 12 | 13 | FUNC(_start) 14 | ldr r0, [sp] @argc 15 | add r1, sp, #4 @argv 16 | 17 | bl main @call main 18 | 19 | L1: 20 | b L1 @dead loop 21 | 22 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/asm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file asm.h 3 | * 4 | * @brief Common macros for asm routines. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #ifndef _ASM_H_ 10 | #define _ASM_H_ 11 | 12 | #define ARG0 r0 13 | #define ARG1 r1 14 | #define ARG2 r2 15 | #define ARG3 r3 16 | 17 | #define ARG4 [sp, #0] 18 | #define ARG5 [sp, #4] 19 | #define ARG6 [sp, #8] 20 | #define ARG7 [sp, #8] 21 | 22 | 23 | #define ALIGN .align 2 24 | #define GLOBAL(x) .global x; x ## : 25 | 26 | #define FUNCSYM(x) .type x,%function 27 | #define DATASYM(x) .type x,%object 28 | #define SIZE(x,s) .size x, s 29 | 30 | #define FUNC(x) .text ; ALIGN ; FUNCSYM(x) ; GLOBAL(x) 31 | #define DATA(x,s) .data ; ALIGN ; DATASYM(x) ; SIZE(x,s) ; GLOBAL(x) 32 | 33 | 34 | #endif /* _ASM_H_ */ 35 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/bits/dev.h: -------------------------------------------------------------------------------- 1 | /** @file dev.h 2 | * 3 | * @brief Defines simulated "devices". 4 | * 5 | * These devices each have an associated condition variable that they signal 6 | * with the given periodicity. Each condition variable also has an associated 7 | * mutex of the same index. 8 | * 9 | * @author Kartik Subramanian 10 | * @date 2008-10-31 11 | */ 12 | 13 | #ifndef BITS_DEV_H 14 | #define BITS_DEV_H 15 | 16 | #define NUM_DEVICES 4 17 | #define PERIOD_DEV0 100 18 | #define PERIOD_DEV1 200 19 | #define PERIOD_DEV2 500 20 | #define PERIOD_DEV3 50 21 | 22 | #endif /* BITS_DEV_H */ 23 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/bits/errno.h: -------------------------------------------------------------------------------- 1 | /* From linux-2.6.18/include/asm-generic/errno-base.h */ 2 | 3 | #ifndef BITS_ERRNO_H 4 | #define BITS_ERRNO_H 5 | 6 | #define EPERM 1 /* Operation not permitted */ 7 | #define ENOENT 2 /* No such file or directory */ 8 | #define ESRCH 3 /* No such process */ 9 | #define EINTR 4 /* Interrupted system call */ 10 | #define EIO 5 /* I/O error */ 11 | #define ENXIO 6 /* No such device or address */ 12 | #define E2BIG 7 /* Argument list too long */ 13 | #define ENOEXEC 8 /* Exec format error */ 14 | #define EBADF 9 /* Bad file number */ 15 | #define ECHILD 10 /* No child processes */ 16 | #define EAGAIN 11 /* Try again */ 17 | #define ENOMEM 12 /* Out of memory */ 18 | #define EACCES 13 /* Permission denied */ 19 | #define EFAULT 14 /* Bad address */ 20 | #define ENOTBLK 15 /* Block device required */ 21 | #define EBUSY 16 /* Device or resource busy */ 22 | #define EEXIST 17 /* File exists */ 23 | #define EXDEV 18 /* Cross-device link */ 24 | #define ENODEV 19 /* No such device */ 25 | #define ENOTDIR 20 /* Not a directory */ 26 | #define EISDIR 21 /* Is a directory */ 27 | #define EINVAL 22 /* Invalid argument */ 28 | #define ENFILE 23 /* File table overflow */ 29 | #define EMFILE 24 /* Too many open files */ 30 | #define ENOTTY 25 /* Not a typewriter */ 31 | #define ETXTBSY 26 /* Text file busy */ 32 | #define EFBIG 27 /* File too large */ 33 | #define ENOSPC 28 /* No space left on device */ 34 | #define ESPIPE 29 /* Illegal seek */ 35 | #define EROFS 30 /* Read-only file system */ 36 | #define EMLINK 31 /* Too many links */ 37 | #define EPIPE 32 /* Broken pipe */ 38 | #define EDOM 33 /* Math argument out of domain of func */ 39 | #define ERANGE 34 /* Math result not representable */ 40 | #define EDEADLOCK 58 /* File locking deadlock error */ 41 | 42 | #define ESCHED 100 /* Unable to schedule */ 43 | 44 | #endif /* BITS_ERRNO_H */ 45 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/bits/fileno.h: -------------------------------------------------------------------------------- 1 | /** @fileno.h 2 | * 3 | * @brief Defines stdin/stdout/stderr file descriptor numbers 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:34:56 -0400 7 | */ 8 | 9 | #ifndef BITS_FILENO_H 10 | #define BITS_FILENO_H 11 | 12 | #define STDIN_FILENO 0 13 | #define STDOUT_FILENO 1 14 | #define STDERR_FILENO 2 15 | 16 | #endif /* BITS_FILENO_H */ 17 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/bits/swi.h: -------------------------------------------------------------------------------- 1 | /** @file swi.h 2 | * 3 | * @brief Defines syscall numbers used in SWI instructions 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:36:02 -0400 7 | * 8 | * @author Kartik Subramanian 9 | * @date 2008-10-31 10 | */ 11 | 12 | #ifndef BITS_SWI_H 13 | #define BITS_SWI_H 14 | 15 | #define SWI_BASE 0x900000 16 | 17 | #define READ_SWI (SWI_BASE + 3) 18 | #define WRITE_SWI (SWI_BASE + 4) 19 | 20 | /* The following are not linux compatible */ 21 | #define TIME_SWI (SWI_BASE + 6) 22 | #define SLEEP_SWI (SWI_BASE + 7) 23 | 24 | #define CREATE_SWI (SWI_BASE + 10) 25 | 26 | #define MUTEX_CREATE (SWI_BASE + 15) 27 | #define MUTEX_LOCK (SWI_BASE + 16) 28 | #define MUTEX_UNLOCK (SWI_BASE + 17) 29 | 30 | #define EVENT_WAIT (SWI_BASE + 20) 31 | 32 | #endif /* BITS_SWI_H */ 33 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/bits/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file types.h 3 | * 4 | * @brief Standard Integer Types and Limits 5 | * Corresponds to ANSI C99 stdint.h, stddef.h and limits.h 6 | * 7 | * @note Other standard foo that needs to be defined are defined here. 8 | */ 9 | 10 | #ifndef _BITS_TYPES_H_ 11 | #define _BITS_TYPES_H_ 12 | 13 | 14 | #ifndef ASSEMBLER 15 | 16 | #define offsetof(type, member) ((size_t)(&(((type *)0)->member))) 17 | 18 | typedef unsigned long size_t; 19 | typedef long ssize_t; 20 | 21 | /* --- Guaranteed length --- */ 22 | 23 | typedef char int8_t; 24 | typedef short int16_t; 25 | typedef int int32_t; 26 | typedef long long int64_t; 27 | 28 | typedef unsigned char uint8_t; 29 | typedef unsigned short uint16_t; 30 | typedef unsigned int uint32_t; 31 | typedef unsigned long long uint64_t; 32 | 33 | /* --- Pointer length --- */ 34 | 35 | typedef int32_t intptr_t; 36 | typedef uint32_t uintptr_t; 37 | 38 | #endif /* ASSEMBLER */ 39 | 40 | /* --- Sizes --- */ 41 | 42 | #define UINT8_MAX 0xff 43 | #define UINT16_MAX 0xffff 44 | #define UINT32_MAX 0xffffffff 45 | #define UINT64_MAX 0xffffffffffffffff 46 | 47 | #define INT8_MAX 0x7f 48 | #define INT16_MAX 0x7fff 49 | #define INT32_MAX 0x7fffffff 50 | #define INT64_MAX 0x7fffffffffffffff 51 | #define INT8_MIN (-INT8_MAX -1) 52 | #define INT16_MIN (-INT16_MAX -1) 53 | #define INT32_MIN (-INT32_MAX -1) 54 | #define INT64_MIN (-INT64_MAX -1) 55 | 56 | #define SIZE_MAX UINT32_MAX 57 | #define SSIZE_MAX INT32_MAX 58 | #define SSIZE_MIN INT32_MIN 59 | 60 | #define CHAR_BIT 8 61 | 62 | #define UCHAR_MAX UINT8_MAX 63 | #define USHRT_MAX UINT16_MAX 64 | #define UINT_MAX UINT32_MAX 65 | #define ULONG_MAX UINT32_MAX 66 | #define ULLONG_MAX UINT64_MAX 67 | 68 | #define SCHAR_MAX INT8_MAX 69 | #define CHAR_MAX SCHAR_MAX 70 | #define SHRT_MAX INT16_MAX 71 | #define INT_MAX INT32_MAX 72 | #define LONG_MAX INT32_MAX 73 | #define LLONG_MAX INT64_MAX 74 | #define SCHAR_MIN INT8_MIN 75 | #define CHAR_MIN SCHAR_MIN 76 | #define SHRT_MIN INT16_MIN 77 | #define INT_MIN INT32_MIN 78 | #define LONG_MIN INT32_MIN 79 | #define LLONG_MIN INT64_MIN 80 | 81 | 82 | #endif /* _BITS_TYPES_H_ */ 83 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/ctype.h: -------------------------------------------------------------------------------- 1 | /** @file ctype.h 2 | * 3 | * @brief Predicates for characters. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | 9 | #ifndef _CTYPE_H_ 10 | #define _CTYPE_H_ 11 | 12 | #include 13 | 14 | INLINE int __attribute__((const)) isascii(int c) 15 | { 16 | return (c >= 0) && (c <= 127); 17 | } 18 | 19 | INLINE int __attribute__((const)) iscntrl(int c) 20 | { 21 | return (c < ' ') || (c > 126); 22 | } 23 | 24 | INLINE int __attribute__((const)) isdigit(int c) 25 | { 26 | return (c >= '0') && (c <= '9'); 27 | } 28 | 29 | INLINE int __attribute__((const)) isgraph(int c) 30 | { 31 | return (c > ' ') && (c <= 126); 32 | } 33 | 34 | INLINE int __attribute__((const)) islower(int c) 35 | { 36 | return (c >= 'a') && (c <= 'z'); 37 | } 38 | 39 | INLINE int __attribute__((const)) isprint(int c) 40 | { 41 | return (c >= ' ') && (c <= 126); 42 | } 43 | 44 | INLINE int __attribute__((const)) isspace(int c) 45 | { 46 | return (c == ' ') || (c == '\f') || (c == '\n') 47 | || (c == '\n') || (c == '\r') || (c == '\t') || (c == '\v'); 48 | } 49 | 50 | INLINE int __attribute__((const)) isupper(int c) 51 | { 52 | return (c >= 'A') && (c <= 'Z'); 53 | } 54 | 55 | INLINE int __attribute__((const)) isxdigit(int c) 56 | { 57 | return isdigit(c) || 58 | ((c >= 'A') && (c <= 'F')) || 59 | ((c >= 'a') && (c <= 'f')); 60 | } 61 | 62 | INLINE int __attribute__((const)) isalpha(int c) 63 | { 64 | return islower(c) || isupper(c); 65 | } 66 | 67 | INLINE int __attribute__((const)) isalnum(int c) 68 | { 69 | return isalpha(c) || isdigit(c); 70 | } 71 | 72 | INLINE int __attribute__((const)) ispunct(int c) 73 | { 74 | return isgraph(c) && !isalnum(c); 75 | } 76 | 77 | INLINE int __attribute__((const)) toupper(int c) 78 | { 79 | return islower(c) ? c - 'a' + 'A' : c; 80 | } 81 | 82 | INLINE int __attribute__((const)) tolower(int c) 83 | { 84 | return isupper(c) ? c - 'A' + 'a' : c; 85 | } 86 | 87 | #endif /* _CTYPE_H_ */ 88 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/errno.h: -------------------------------------------------------------------------------- 1 | /** @file errno.h 2 | * 3 | * @brief Declares the global errno variable 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:37:12 -0400 7 | */ 8 | 9 | #ifndef ERRNO_H 10 | #define ERRNO_H 11 | 12 | #include 13 | 14 | #ifndef ASSEMBLER 15 | 16 | extern int errno; 17 | 18 | #endif /* ASSEMBLER */ 19 | 20 | #endif /* ERRNO_H */ 21 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/inline.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file inline.h 3 | * 4 | * @brief GCC specific dances to guarantee correct inlining. 5 | * 6 | * Gcc will never generate code for an extern inline function on its own. Any 7 | * occurences of a call to an extern inline function will be expanded inline. 8 | * If the address of an extern inline function is taken, it is counted as an 9 | * external reference. 10 | * 11 | * To use this feature correctly, we put the code for all functions that we want 12 | * to inline in headers as `extern inline' and then put a single copy of the 13 | * function without extern inline in a library file. This will cause most calls 14 | * to the function to get inlined. Any remaining uses of the function (such as 15 | * taking the address of the function) will now refer to the single library copy 16 | * of the function. 17 | * 18 | * @author Kartik Subramanian 19 | * 20 | * @date 2008-07-08 21 | */ 22 | 23 | /* No guards... on purpose! */ 24 | 25 | #ifdef INLINE 26 | #undef INLINE 27 | #endif 28 | 29 | #ifndef IMPLEMENTATION 30 | #define INLINE extern inline 31 | #else 32 | #define INLINE 33 | #endif 34 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/lock.h: -------------------------------------------------------------------------------- 1 | /** @file lock.h 2 | * 3 | * @brief Declaration of locking and synchronization primitives. 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #ifndef _LOCK_H_ 12 | #define _LOCK_H_ 13 | 14 | int mutex_create(void); 15 | int mutex_lock(int mutex); 16 | int mutex_unlock(int mutex); 17 | 18 | #endif /* _LOCK_H_ */ 19 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/stdarg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdarg.h: Defines variable argument macros & typedef 3 | * 4 | * Author: Mike Kasick 5 | * Date: Sun, 14 Oct 2007 00:12:03 -0400 6 | */ 7 | 8 | #ifndef STDARG_H 9 | #define STDARG_H 10 | 11 | #define va_start(ap, last) __builtin_va_start(ap, last) 12 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 13 | #define va_end(ap) __builtin_va_end(ap) 14 | #define va_copy(dest, src) __builtin_va_copy(dest, src) 15 | 16 | typedef __builtin_va_list va_list; 17 | 18 | #endif /* STDARG_H */ 19 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/stdio.h: -------------------------------------------------------------------------------- 1 | /** @stdio.h 2 | * 3 | * @brief Declares C input/output library functions 4 | * 5 | * Modified code from 15-410's 410user libraries. 6 | * 7 | * @author Kartik Subramanian 8 | * @date 2008-10-30 9 | */ 10 | /* 11 | * Copyright (c) 1996-1994 The University of Utah and 12 | * the Computer Systems Laboratory at the University of Utah (CSL). 13 | * All rights reserved. 14 | * 15 | * Permission to use, copy, modify and distribute this software is hereby 16 | * granted provided that (1) source code retains these copyright, permission, 17 | * and disclaimer notices, and (2) redistributions including binaries 18 | * reproduce the notices in supporting documentation, and (3) all advertising 19 | * materials mentioning features or use of this software display the following 20 | * acknowledgement: ``This product includes software developed by the 21 | * Computer Systems Laboratory at the University of Utah.'' 22 | * 23 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 24 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 25 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 26 | * 27 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 28 | * improvements that they make and grant CSL redistribution rights. 29 | */ 30 | #ifndef _FLUX_MC_STDIO_H 31 | #define _FLUX_MC_STDIO_H 32 | 33 | #ifndef ASSEMBLER 34 | #include 35 | #include 36 | 37 | int putchar(int __c); 38 | int puts(const char *__str) __attribute__((nonnull)); 39 | int printf(const char *__format, ...) 40 | __attribute__((nonnull (1), format (printf, 1, 2))); 41 | int vprintf(const char *__format, va_list __vl) 42 | __attribute__((nonnull)); 43 | int sprintf(char *__dest, const char *__format, ...) 44 | __attribute__((nonnull (1, 2), format (printf, 2, 3))); 45 | int snprintf(char *__dest, size_t __size, const char *__format, ...) 46 | __attribute__((nonnull (1, 3), format (printf, 3, 4))); 47 | int vsprintf(char *__dest, const char *__format, va_list __vl) 48 | __attribute__((nonnull (1, 2))); 49 | int vsnprintf(char *__dest, size_t __size, const char *__format, va_list __vl) 50 | __attribute__((nonnull (1, 3))); 51 | int sscanf(const char *__str, const char *__format, ...) 52 | __attribute__((nonnull (1, 2), format (printf, 2, 3))); 53 | void hexdump(void *buf, size_t len); 54 | 55 | #endif /* !ASSEMBLER */ 56 | 57 | #endif /* _FLUX_MC_STDIO_H */ 58 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/stdlib.h: -------------------------------------------------------------------------------- 1 | /** @stdlib.h 2 | * 3 | * @brief Declares C standard library functions 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:38:16 -0400 7 | * 8 | * Merged with code from 15-410's 410user libraries. Thank you guys! 9 | * @author Kartik Subramanian 10 | * @date 2008-10-30 11 | */ 12 | 13 | #ifndef STDLIB_H 14 | #define STDLIB_H 15 | 16 | long atol(const char* str) __attribute__((const, nonnull)); 17 | int atoi(const char* str) __attribute__((const, nonnull)); 18 | 19 | long strtol(const char* p, char** out_p, int base) __attribute__((const, nonnull)); 20 | unsigned long strtoul(const char* p, char** out_p, int base) __attribute__((const, nonnull)); 21 | 22 | int rand(void); 23 | void srand(unsigned int seed); 24 | 25 | #endif /* STDLIB_H */ 26 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/string.h: -------------------------------------------------------------------------------- 1 | /** @file string.h 2 | * 3 | * Taken from 15-410's 410lib files. 4 | * Adapted for use in 18-349. 5 | * 6 | * @author Kartik Subramanian 7 | * @date 2008-10-30 8 | */ 9 | /* 10 | * Copyright (c) 1994 The University of Utah and 11 | * the Computer Systems Laboratory at the University of Utah (CSL). 12 | * All rights reserved. 13 | * 14 | * Permission to use, copy, modify and distribute this software is hereby 15 | * granted provided that (1) source code retains these copyright, permission, 16 | * and disclaimer notices, and (2) redistributions including binaries 17 | * reproduce the notices in supporting documentation, and (3) all advertising 18 | * materials mentioning features or use of this software display the following 19 | * acknowledgement: ``This product includes software developed by the 20 | * Computer Systems Laboratory at the University of Utah.'' 21 | * 22 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 23 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 24 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 25 | * 26 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 27 | * improvements that they make and grant CSL redistribution rights. 28 | */ 29 | #ifndef _FLUX_MC_STRING_H_ 30 | #define _FLUX_MC_STRING_H_ 31 | 32 | #include 33 | 34 | size_t strlen(const char *__s) __attribute__((const, nonnull)); 35 | char *strcpy(char *__dest, const char *__src) __attribute__((nonnull)); 36 | char *strncpy(char *__dest, const char *__src, size_t __n) __attribute__((nonnull)); 37 | char *strdup(const char *__s) __attribute__((nonnull)); 38 | char *strcat(char *__dest, const char *__src) __attribute__((nonnull)); 39 | char *strncat(char *__dest, const char *__src, size_t __n) __attribute__((nonnull)); 40 | int strcmp(const char *__a, const char *__b) __attribute__((const, nonnull)); 41 | int strncmp(const char *__a, const char *__b, size_t __n) __attribute__((const, nonnull)); 42 | char *strchr(const char *__s, int __c) __attribute__((const, nonnull)); 43 | char *strrchr(const char *__s, int __c) __attribute__((const, nonnull)); 44 | char *strstr(const char *__haystack, const char *__needle) __attribute__((const, nonnull)); 45 | char *strpbrk(const char *__s1, const char *__s2) __attribute__((const, nonnull)); 46 | size_t strspn(const char *__s1, const char *__s2) __attribute__((const, nonnull)); 47 | size_t strcspn(const char *__s1, const char *__s2) __attribute__((const, nonnull)); 48 | 49 | void *memset(void *__to, int __ch, size_t __n) __attribute__((nonnull)); 50 | int memcmp(const void *s1v, const void *s2v, size_t size) __attribute__((const, nonnull)); 51 | 52 | /* FIXME These are defined here only by tradition... we should move them. */ 53 | void *memcpy(void *__to, const void *__from, size_t __n) __attribute__((nonnull)); 54 | void *memmove(void *__to, const void *__from, size_t __n) __attribute__((nonnull)); 55 | 56 | #endif /* _FLUX_MC_STRING_H_ */ 57 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/sys/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * types.h: Defines typedefs used in libc 3 | * 4 | * Author: Mike Kasick 5 | * Date: Sun, 07 Oct 2007 01:38:48 -0400 6 | */ 7 | 8 | #ifndef SYS_TYPES_H 9 | #define SYS_TYPES_H 10 | 11 | #include 12 | 13 | #endif /* SYS_TYPES_H */ 14 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/task.h: -------------------------------------------------------------------------------- 1 | /** @file task.h 2 | * 3 | * @brief Declares task creation interface 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-11-21 7 | */ 8 | 9 | #ifndef TASK_H 10 | #define TASK_H 11 | 12 | #include 13 | 14 | /** 15 | * A task takes an arbitrary parameter and begins execution. 16 | * Task function are not allowed to exit or crash under any circumstance. 17 | */ 18 | typedef void (*task_fun_t)(void*); 19 | 20 | struct task 21 | { 22 | task_fun_t lambda; /**< The root function of this task */ 23 | void* data; /**< Argument to the root function */ 24 | void* stack_pos; /**< The starting position of the task's sp */ 25 | unsigned long C; /**< The worst-case computation time */ 26 | unsigned long T; /**< The task's period */ 27 | }; 28 | typedef struct task task_t; 29 | 30 | 31 | int task_create(task_t* tasks, size_t num_tasks); 32 | 33 | 34 | #endif /* TASK_H */ 35 | -------------------------------------------------------------------------------- /lab4/tasks/libc/include/unistd.h: -------------------------------------------------------------------------------- 1 | /** @file unistd.h 2 | * 3 | * @brief Declares C standard library functions 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:38:30 -0400 7 | */ 8 | 9 | #ifndef UNISTD_H 10 | #define UNISTD_H 11 | 12 | #include 13 | #include 14 | 15 | #define NUM_DEVICES 4 16 | #define PERIOD_DEV0 100 17 | #define PERIOD_DEV1 200 18 | #define PERIOD_DEV2 500 19 | #define PERIOD_DEV3 50 20 | 21 | ssize_t read(int fd, void *buf, size_t count); 22 | ssize_t write(int fd, const void *buf, size_t count); 23 | unsigned long time(void); 24 | void sleep(unsigned long millis); 25 | int event_wait(unsigned int dev); 26 | 27 | #endif /* UNISTD_H */ 28 | -------------------------------------------------------------------------------- /lab4/tasks/libc/libc.mk: -------------------------------------------------------------------------------- 1 | TLIBC = $(TLIBCDIR)/libc.a 2 | TSTART = $(TLIBCDIR)/crt0.o 3 | 4 | TLIBC_GLOBAL_OBJS := raise.o 5 | TLIBC_GLOBAL_OBJS := $(TLIBC_GLOBAL_OBJS:%=$(TLIBCDIR)/%) 6 | 7 | TLIBC_LIBS = swi string stdio stdlib 8 | TLIBC_MKS = $(TLIBC_LIBS:%=$(TLIBCDIR)/%/libc.mk) 9 | 10 | include $(TLIBC_MKS) 11 | 12 | TLIBC_OBJS += $(TLIBC_GLOBAL_OBJS) 13 | ALL_OBJS += $(TLIBC_OBJS) $(TSTART) 14 | ALL_CLEANS += $(TLIBC) 15 | 16 | $(TLIBC) : $(TLIBC_OBJS) 17 | 18 | @echo AR $(notdir $@) 19 | @cp $(LIBGCC) $@ 20 | @$(AR) rs $@ $^ -------------------------------------------------------------------------------- /lab4/tasks/libc/raise.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file raise.c 3 | * 4 | * @brief Divide by zero exception handler. 5 | * 6 | * @author Kartik Subramanian 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | void raise(void) 13 | { 14 | puts("Divide by zero\n"); 15 | while(1); 16 | } 17 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/doprnt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #ifndef __DOPRNT_H_INCLUDED__ 23 | #define __DOPRNT_H_INCLUDED__ 24 | 25 | #include 26 | 27 | typedef enum 28 | { 29 | FALSE = 0, 30 | TRUE 31 | } boolean_t; 32 | 33 | void _doprnt( 34 | const char *fmt, 35 | va_list args, 36 | int radix, /* default radix - for '%r' */ 37 | void (*putc)(char*, int), /* character output */ 38 | char *putc_arg); /* argument for putc */ 39 | 40 | #endif /* __DOPRNT_H_INCLUDED__ */ 41 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/doscan.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1993 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | /* 27 | * File: sscanf.c 28 | * Author: Alessandro Forin, Carnegie Mellon University 29 | * Date: 3/93 30 | * 31 | * Parse trivially simple strings 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include "doscan.h" 38 | 39 | /* 40 | * All I need is a miracle ... 41 | * to keep this from growing like all the other sscanf! 42 | */ 43 | int _doscan(const unsigned char *fmt, va_list vp, 44 | int (*getc)(void *getc_arg), 45 | void (*ungetc)(int c, void *getc_arg), 46 | void *getc_arg) 47 | { 48 | int c; 49 | boolean_t neg; 50 | boolean_t discard; 51 | int vals = 0; 52 | 53 | while ((c = *fmt++) != 0) 54 | { 55 | if (c != '%') 56 | { 57 | if (isspace(c)) 58 | { 59 | while (isspace(c = getc(getc_arg))); 60 | ungetc(c, getc_arg); 61 | continue; 62 | } 63 | else if (c == getc(getc_arg)) 64 | continue; 65 | else 66 | break; /* mismatch */ 67 | } 68 | 69 | discard = 0; 70 | 71 | more_fmt: 72 | 73 | c = *fmt++; 74 | 75 | switch (c) { 76 | 77 | case 'd': 78 | { 79 | long n = 0; 80 | 81 | c = getc(getc_arg); 82 | 83 | neg = c == '-'; 84 | if (neg) c = getc(getc_arg); 85 | 86 | while (c >= '0' && c <= '9') 87 | { 88 | n = n * 10 + (c - '0'); 89 | c = getc(getc_arg); 90 | } 91 | ungetc(c, getc_arg); 92 | 93 | if (neg) n = -n; 94 | 95 | /* done, store it away */ 96 | if (!discard) 97 | { 98 | int *p = va_arg(vp, int *); 99 | *p = n; 100 | } 101 | 102 | break; 103 | } 104 | 105 | case 'x': 106 | { 107 | long n = 0; 108 | 109 | c = getc(getc_arg); 110 | 111 | neg = c == '-'; 112 | if (neg) c = getc(getc_arg); 113 | 114 | while (1) 115 | { 116 | if ((c >= '0') && (c <= '9')) 117 | n = n * 16 + (c - '0'); 118 | else if ((c >= 'a') && (c <= 'f')) 119 | n = n * 16 + (c - 'a' + 10); 120 | else if ((c >= 'A') && (c <= 'F')) 121 | n = n * 16 + (c - 'A' + 10); 122 | else 123 | break; 124 | c = getc(getc_arg); 125 | } 126 | ungetc(c, getc_arg); /* retract lookahead */ 127 | 128 | if (neg) n = -n; 129 | 130 | /* done, store it away */ 131 | if (!discard) 132 | { 133 | int *p = va_arg(vp, int *); 134 | *p = n; 135 | } 136 | 137 | break; 138 | } 139 | 140 | case 's': 141 | { 142 | char *buf = 0; 143 | 144 | if (!discard) 145 | buf = va_arg(vp, char *); 146 | 147 | c = getc(getc_arg); 148 | while (!isspace(c)) 149 | { 150 | if (!discard) 151 | *buf++ = c; 152 | c = getc(getc_arg); 153 | } 154 | ungetc(c, getc_arg); /* retract lookahead */ 155 | 156 | if (!discard) 157 | *buf = 0; 158 | 159 | break; 160 | } 161 | 162 | case '*': 163 | discard = 1; 164 | goto more_fmt; 165 | 166 | default: 167 | break; 168 | } 169 | 170 | if (!discard) 171 | vals++; 172 | } 173 | 174 | return vals; 175 | } 176 | 177 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/doscan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #ifndef __DOSCAN_H_INCLUDED__ 23 | #define __DOSCAN_H_INCLUDED__ 24 | 25 | typedef enum 26 | { 27 | FALSE = 0, 28 | TRUE 29 | } boolean_t; 30 | 31 | int _doscan(const unsigned char *fmt, va_list vp, 32 | int (*getc)(void *getc_arg), 33 | void (*ungetc)(int c, void *getc_arg), 34 | void *getc_arg); 35 | 36 | #endif /* __DOSCAN_H_INCLUDED__ */ 37 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/hexdump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | /* 26 | * Print a buffer hexdump style. Example: 27 | * 28 | * .---------------------------------------------------------------------------. 29 | * | 00000000 2e2f612e 6f757400 5445524d 3d787465 ./a.out.TERM=xte | 30 | * | 00000010 726d0048 4f4d453d 2f616673 2f63732e rm.HOME=/afs/cs. | 31 | * | 00000020 75746168 2e656475 2f686f6d 652f6c6f utah.edu/home/lo | 32 | * | 00000030 6d657700 5348454c 4c3d2f62 696e2f74 mew.SHELL=/bin/t | 33 | * | 00000040 63736800 4c4f474e 414d453d 6c6f6d65 csh.LOGNAME=lome | 34 | * | 00000050 77005553 45523d6c 6f6d6577 00504154 w.USER=lomew.PAT | 35 | * | 00000060 483d2f61 66732f63 732e7574 61682e65 H=/afs/cs.utah.e | 36 | * | 00000070 64752f68 6f6d652f 6c6f6d65 772f6269 du/home/lomew/bi | 37 | * | 00000080 6e2f4073 79733a2f 6166732f 63732e75 n/@sys:/afs/cs.u | 38 | * | 00000090 7461682e 6564 tah.ed | 39 | * `---------------------------------------------------------------------------' 40 | * 41 | * It might be useful to have an option for printing out little-endianly. 42 | * Adapted from Godmar's hook.c. 43 | */ 44 | void hexdump(void *buf, size_t len) 45 | { 46 | size_t i, j; 47 | char *b = (char *)buf; 48 | 49 | printf(".---------------------------------------------------------------------------.\n"); 50 | for (i = 0; i < len; i += 16) { 51 | printf("| %08lx ", i); 52 | for (j = i; j < i+16; j++) { 53 | if (j % 4 == 0) 54 | printf(" "); 55 | if (j >= len) 56 | printf(" "); 57 | else 58 | printf("%02x", (unsigned char)b[j]); 59 | } 60 | 61 | printf(" "); 62 | for (j = i; j < i+16; j++) 63 | if (j >= len) 64 | printf(" "); 65 | else 66 | printf("%c", isgraph(b[j]) ? b[j] : '.'); 67 | printf(" |\n"); 68 | } 69 | printf("`---------------------------------------------------------------------------'\n"); 70 | } 71 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/libc.mk: -------------------------------------------------------------------------------- 1 | TLIBC_STDIO_OBJS := doprnt.o doscan.o hexdump.o printf.o putchar.o puts.o \ 2 | sprintf.o sscanf.o 3 | TLIBC_STDIO_OBJS := $(TLIBC_STDIO_OBJS:%=$(TLIBCDIR)/stdio/%) 4 | TLIBC_OBJS += $(TLIBC_STDIO_OBJS) 5 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/printf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1993-1989 Carnegie Mellon University. 4 | * Copyright (c) 1994 The University of Utah and 5 | * the Computer Systems Laboratory (CSL). 6 | * All rights reserved. 7 | * 8 | * Permission to use, copy, modify and distribute this software and its 9 | * documentation is hereby granted, provided that both the copyright 10 | * notice and this permission notice appear in all copies of the 11 | * software, derivative works or modified versions, and any portions 12 | * thereof, and that both notices appear in supporting documentation. 13 | * 14 | * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF 15 | * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY 16 | * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF 17 | * THIS SOFTWARE. 18 | * 19 | * Carnegie Mellon requests users of this software to return to 20 | * 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 | * School of Computer Science 23 | * Carnegie Mellon University 24 | * Pittsburgh PA 15213-3890 25 | * 26 | * any improvements or extensions that they make and grant Carnegie Mellon 27 | * the rights to redistribute these changes. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include "doprnt.h" 34 | 35 | /* This version of printf is implemented in terms of putchar and puts. */ 36 | 37 | #define PRINTF_BUFMAX 128 38 | 39 | struct printf_state { 40 | char buf[PRINTF_BUFMAX]; 41 | unsigned int index; 42 | }; 43 | 44 | static void flush(struct printf_state *state) 45 | { 46 | state->buf[state->index] = 0; 47 | write(STDOUT_FILENO, state->buf, state->index); 48 | 49 | state->index = 0; 50 | } 51 | 52 | static void printf_char(char *arg, int c) 53 | { 54 | struct printf_state *state = (struct printf_state *) arg; 55 | 56 | if (c == '\n') 57 | { 58 | state->buf[state->index] = 0; 59 | puts(state->buf); 60 | state->index = 0; 61 | } 62 | else if ((c == 0) || (state->index >= PRINTF_BUFMAX-1)) 63 | { 64 | flush(state); 65 | putchar(c); 66 | } 67 | else 68 | { 69 | state->buf[state->index] = c; 70 | state->index++; 71 | } 72 | } 73 | 74 | /* 75 | * Printing (to console) 76 | */ 77 | int vprintf(const char *fmt, va_list args) 78 | { 79 | struct printf_state state; 80 | 81 | state.index = 0; 82 | _doprnt(fmt, args, 0, (void (*)(char*, int))printf_char, (char *) &state); 83 | 84 | if (state.index != 0) 85 | flush(&state); 86 | 87 | /* _doprnt currently doesn't pass back error codes, 88 | so just assume nothing bad happened. */ 89 | return 0; 90 | } 91 | 92 | int 93 | printf(const char *fmt, ...) 94 | { 95 | va_list args; 96 | int err; 97 | 98 | va_start(args, fmt); 99 | err = vprintf(fmt, args); 100 | va_end(args); 101 | 102 | return err; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/putchar.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | /* 15-410 mods by de0u 2008-09-02 ... */ 23 | /* Changed 410's syscall to 349's write -- ksubrama 2008-10-30*/ 24 | #include 25 | #include 26 | 27 | int putchar(int c) 28 | { 29 | write(STDOUT_FILENO, (char *)&c, sizeof(c)); 30 | return c; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/puts.c: -------------------------------------------------------------------------------- 1 | /** @file puts.c 2 | * 3 | * @brief Uses the write syscall to write out a string. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-31 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | int puts(const char *s) 13 | { 14 | write(STDOUT_FILENO, s, strlen(s)); 15 | write(STDOUT_FILENO, "\n", 1); 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/sprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mach Operating System 3 | * Copyright (c) 1991,1990,1989 Carnegie Mellon University 4 | * All Rights Reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software and its 7 | * documentation is hereby granted, provided that both the copyright 8 | * notice and this permission notice appear in all copies of the 9 | * software, derivative works or modified versions, and any portions 10 | * thereof, and that both notices appear in supporting documentation. 11 | * 12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 | * 16 | * Carnegie Mellon requests users of this software to return to 17 | * 18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 | * School of Computer Science 20 | * Carnegie Mellon University 21 | * Pittsburgh PA 15213-3890 22 | * 23 | * any improvements or extensions that they make and grant Carnegie Mellon 24 | * the rights to redistribute these changes. 25 | */ 26 | 27 | #include 28 | #include 29 | #include "doprnt.h" 30 | 31 | #define SPRINTF_UNLIMITED -1 32 | struct sprintf_state { 33 | char *buf; 34 | int len; 35 | int max; 36 | }; 37 | 38 | static void savechar(char *arg, int c) 39 | { 40 | struct sprintf_state *state = (struct sprintf_state *)arg; 41 | 42 | if (state->max != SPRINTF_UNLIMITED) 43 | { 44 | if (state->len == state->max) 45 | return; 46 | } 47 | 48 | state->len++; 49 | *state->buf = c; 50 | state->buf++; 51 | } 52 | 53 | int vsprintf(char *s, const char *fmt, va_list args) 54 | { 55 | struct sprintf_state state; 56 | state.max = SPRINTF_UNLIMITED; 57 | state.len = 0; 58 | state.buf = s; 59 | 60 | _doprnt(fmt, args, 0, (void (*)(char*, int)) savechar, (char *) &state); 61 | *(state.buf) = '\0'; 62 | 63 | return state.len; 64 | } 65 | 66 | int vsnprintf(char *s, size_t size, const char *fmt, va_list args) 67 | { 68 | struct sprintf_state state; 69 | state.max = size; 70 | state.len = 0; 71 | state.buf = s; 72 | 73 | _doprnt(fmt, args, 0, (void (*)(char*, int)) savechar, (char *) &state); 74 | *(state.buf) = '\0'; 75 | 76 | return state.len; 77 | } 78 | 79 | int sprintf(char *s, const char *fmt, ...) 80 | { 81 | va_list args; 82 | int err; 83 | 84 | va_start(args, fmt); 85 | err = vsprintf(s, fmt, args); 86 | va_end(args); 87 | 88 | return err; 89 | } 90 | 91 | int snprintf(char *s, size_t size, const char *fmt, ...) 92 | { 93 | va_list args; 94 | int err; 95 | 96 | va_start(args, fmt); 97 | err = vsnprintf(s, size, fmt, args); 98 | va_end(args); 99 | 100 | return err; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdio/sscanf.c: -------------------------------------------------------------------------------- 1 | /** @file sscanf.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | 34 | #include 35 | #include 36 | #include "doscan.h" 37 | 38 | static int readchar(void* arg) 39 | { 40 | return *(*(unsigned char**)arg)++; 41 | } 42 | 43 | static void unchar(int c __attribute__((unused)), void* arg) 44 | { 45 | c=c; 46 | (*(unsigned char**)arg)--; 47 | } 48 | 49 | int vsscanf(const char* s, const char* fmt, va_list args) 50 | { 51 | return _doscan((const unsigned char*)fmt, args, readchar, unchar, &s); 52 | } 53 | 54 | int sscanf(const char *s, const char *fmt, ...) 55 | { 56 | int ret; 57 | va_list args; 58 | 59 | va_start(args, fmt); 60 | ret = vsscanf(s, fmt, args); 61 | va_end(args); 62 | 63 | return ret; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/atoi.c: -------------------------------------------------------------------------------- 1 | /** @file atoi.c 2 | * 3 | * @brief Implements atoi -- man atoi for info. 4 | * 5 | * Imported from 15-410's 410user. 6 | * 7 | * @author Unknown souls who worked on mbermanref 8 | * @author Kartik Subramanian 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | long atol(const char* str) 15 | { 16 | long n = 0; 17 | 18 | while (isdigit(*str)) 19 | { 20 | n = n * 10 + *str - '0'; 21 | str++; 22 | } 23 | 24 | return n; 25 | } 26 | 27 | int atoi(const char* str) 28 | { 29 | return (int)atol(str); 30 | } 31 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/ctype.c: -------------------------------------------------------------------------------- 1 | /** @file ctype.c 2 | * 3 | * @brief Implementation of inline ctype.h functions. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | 9 | #define IMPLEMENTATION 10 | #include 11 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/errno.c: -------------------------------------------------------------------------------- 1 | /** @file errno.c 2 | * 3 | * @brief Defines the global errno variable 4 | * 5 | * @author Mike Kasick 6 | * @date Sun, 07 Oct 2007 01:31:00 -0400 7 | */ 8 | 9 | int errno = 0; 10 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/libc.mk: -------------------------------------------------------------------------------- 1 | TLIBC_STDLIB_OBJS := errno.o ctype.o atoi.o strtol.o strtoul.o rand.o 2 | TLIBC_STDLIB_OBJS := $(TLIBC_STDLIB_OBJS:%=$(TLIBCDIR)/stdlib/%) 3 | TLIBC_OBJS += $(TLIBC_STDLIB_OBJS) 4 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/rand.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | static unsigned seed[2]; 22 | 23 | int 24 | rand(void) 25 | { 26 | seed[0] += 0xa859c317; 27 | seed[0] += (seed[1] << 13) | (seed[1] >> 19); 28 | seed[1] += seed[0]; 29 | return seed[0] & 0x7FFFFFFF; 30 | } 31 | 32 | void 33 | srand(unsigned new_seed) 34 | { 35 | seed[0] = seed[1] = new_seed; 36 | } 37 | 38 | #if 0 /* test code */ 39 | 40 | #define CYCLES 100000000 41 | 42 | void main(int argc, char **argv) 43 | { 44 | unsigned orig_seed = atol(argv[1]); 45 | int i; 46 | 47 | srand(orig_seed); 48 | for(i = 0; i < CYCLES; i++) 49 | { 50 | int r = rand(); 51 | /*printf("%08x\n", r);*/ 52 | if ((seed[0] == orig_seed) && (seed[1] == orig_seed)) 53 | { 54 | printf("repeates after %d cycles\n", i); 55 | exit(0); 56 | } 57 | } 58 | printf("still not repeating after %d cycles\n", CYCLES); 59 | } 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/strtol.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | long strtol(const char *p, char **out_p, int base) 27 | { 28 | long v = 0; 29 | int is_neg = 0; 30 | 31 | while (isspace(*p)) 32 | p++; 33 | if (*p == '-') 34 | is_neg = 1, p++; 35 | else if (*p == '+') 36 | is_neg = 0; 37 | if (((base == 16) || (base == 0)) && 38 | ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) 39 | { 40 | p += 2; 41 | base = 16; 42 | } 43 | if (base == 0) 44 | { 45 | if (*p == '0') 46 | base = 8; 47 | else 48 | base = 10; 49 | } 50 | while (1) 51 | { 52 | char c = *p; 53 | if ((c >= '0') && (c <= '9') && (c - '0' < base)) 54 | v = (v * base) + (c - '0'); 55 | else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) 56 | v = (v * base) + (c - 'a' + 10); 57 | else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) 58 | v = (v * base) + (c - 'A' + 10); 59 | else 60 | break; 61 | p++; 62 | } 63 | if (is_neg) 64 | v = -v; 65 | if (out_p) *out_p = (char*)p; 66 | return v; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /lab4/tasks/libc/stdlib/strtoul.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995-1994 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | unsigned long strtoul(const char *p, char **out_p, int base) 27 | { 28 | unsigned long v = 0; 29 | 30 | while (isspace(*p)) 31 | p++; 32 | if (((base == 16) || (base == 0)) && 33 | ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) 34 | { 35 | p += 2; 36 | base = 16; 37 | } 38 | if (base == 0) 39 | { 40 | if (*p == '0') 41 | base = 8; 42 | else 43 | base = 10; 44 | } 45 | while (1) 46 | { 47 | char c = *p; 48 | if ((c >= '0') && (c <= '9') && (c - '0' < base)) 49 | v = (v * base) + (c - '0'); 50 | else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) 51 | v = (v * base) + (c - 'a' + 10); 52 | else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) 53 | v = (v * base) + (c - 'A' + 10); 54 | else 55 | break; 56 | p++; 57 | } 58 | 59 | if (out_p) *out_p = (char*)p; 60 | return v; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/libc.mk: -------------------------------------------------------------------------------- 1 | TLIBC_STRING_OBJS := memmove.o memcmp.o memset.o \ 2 | strcat.o strchr.o strcmp.o strcpy.o strcspn.o strlen.o \ 3 | strncat.o strncmp.o strncpy.o strpbrk.o strrchr.o strspn.o strstr.o 4 | TLIBC_STRING_OBJS := $(TLIBC_STRING_OBJS:%=$(TLIBCDIR)/string/%) 5 | TLIBC_OBJS += $(TLIBC_STRING_OBJS) 6 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/memcmp.c: -------------------------------------------------------------------------------- 1 | /** @file memcmp.c 2 | * 3 | * Taken from 15-410's 410user. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | /* 34 | * File: limach/memcmp.c 35 | * Author: Robert V. Baron at Carnegie Mellon 36 | * Date: Oct 13, 1992 37 | * Abstract: 38 | * strcmp (s1, s2) compares the strings "s1" and "s2". 39 | * It returns 0 if the strings are identical. It returns 40 | * > 0 if the first character that differs into two strings 41 | * is larger in s1 than in s2 or if s1 is longer than s2 and 42 | * the contents are identical up to the length of s2. 43 | * It returns < 0 if the first differing character is smaller 44 | * in s1 than in s2 or if s1 is shorter than s2 and the 45 | * contents are identical upto the length of s1. 46 | */ 47 | 48 | #include 49 | 50 | #ifndef __GNUC__ /* GNU C has builtin memcmp() */ 51 | int memcmp(const void *s1v, const void *s2v, size_t size) 52 | { 53 | const char *s1 = s1v, *s2 = s2v; 54 | unsigned int a, b; 55 | 56 | while (size-- > 0) { 57 | if ((a = *s1++) != (b = *s2++)) 58 | return (a-b); 59 | } 60 | 61 | return 0; 62 | } 63 | #endif /* __GNUC__ */ 64 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/memmove.c: -------------------------------------------------------------------------------- 1 | /** @file memmove.c 2 | * 3 | * @author Kartik Subramanian 4 | * @date 2008-10-30 5 | */ 6 | 7 | #include 8 | 9 | void* memmove(void* dest, const void* src, size_t count) 10 | { 11 | char* d; 12 | const char* s; 13 | size_t i; 14 | 15 | d = (char*)dest; 16 | s = (const char*)src; 17 | 18 | if ((uintptr_t)d < (uintptr_t)s) 19 | for (i = 0; i != count; i++) 20 | d[i] = s[i]; 21 | else 22 | for (i = count; i != 0; i--) 23 | d[i-1] = s[i-1]; 24 | 25 | return dest; 26 | } 27 | 28 | void* memcpy(void* dest, const void* src, size_t count) 29 | { 30 | return memmove(dest, src, count); 31 | } 32 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/memset.c: -------------------------------------------------------------------------------- 1 | /** @file memset.c 2 | * 3 | * Modified from 15-410's 410user library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Copyright (c) 1995 The University of Utah and 10 | * the Computer Systems Laboratory at the University of Utah (CSL). 11 | * All rights reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software is hereby 14 | * granted provided that (1) source code retains these copyright, permission, 15 | * and disclaimer notices, and (2) redistributions including binaries 16 | * reproduce the notices in supporting documentation, and (3) all advertising 17 | * materials mentioning features or use of this software display the following 18 | * acknowledgement: ``This product includes software developed by the 19 | * Computer Systems Laboratory at the University of Utah.'' 20 | * 21 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 22 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 23 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 24 | * 25 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 26 | * improvements that they make and grant CSL redistribution rights. 27 | */ 28 | 29 | #include 30 | 31 | void* memset(void *tov, int c, size_t len) 32 | { 33 | char *to = tov; 34 | 35 | while (len-- > 0) 36 | *to++ = c; 37 | 38 | return tov; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strcat.c: -------------------------------------------------------------------------------- 1 | /** @file strcat.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | 34 | #include 35 | 36 | char* strcat(char* s, const char* add) 37 | { 38 | char *ret = s; 39 | 40 | while (*s) s++; 41 | 42 | while ((*s++ = *add++) != 0); 43 | 44 | return ret; 45 | } 46 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | 24 | char *strchr(const char *s, int c) 25 | { 26 | while (1) 27 | { 28 | if (*s == c) 29 | return (char*)s; 30 | if (*s == 0) 31 | return 0; 32 | s++; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strcmp.c: -------------------------------------------------------------------------------- 1 | /** @file strcmp.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | /* 34 | * File: limach/strcmp.c 35 | * Author: Robert V. Baron at Carnegie Mellon 36 | * Date: Oct 13, 1992 37 | * Abstract: 38 | * strcmp (s1, s2) compares the strings "s1" and "s2". 39 | * It returns 0 if the strings are identical. It returns 40 | * > 0 if the first character that differs into two strings 41 | * is larger in s1 than in s2 or if s1 is longer than s2 and 42 | * the contents are identical up to the length of s2. 43 | * It returns < 0 if the first differing character is smaller 44 | * in s1 than in s2 or if s1 is shorter than s2 and the 45 | * contents are identical upto the length of s1. 46 | */ 47 | 48 | #include 49 | 50 | int strcmp(const char *s1, const char *s2) 51 | { 52 | unsigned int a, b; 53 | 54 | while ( (a = *s1++), (b = *s2++), a && b) 55 | { 56 | if (a != b) 57 | return (a-b); 58 | } 59 | 60 | return a-b; 61 | } 62 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strcpy.c: -------------------------------------------------------------------------------- 1 | /** @file strcpy.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | /* 34 | * File: libmach_sa/strcpy.c 35 | * Author: Robert V. Baron at Carnegie Mellon 36 | * Date: Oct 13, 1992 37 | * Abstract: 38 | * strcpy copies the contents of the string "from" including 39 | * the null terminator to the string "to". A pointer to "to" 40 | * is returned. 41 | */ 42 | 43 | #include 44 | 45 | char* strcpy(char *to, const char *from) 46 | { 47 | char *ret = to; 48 | 49 | while ((*to++ = *from++) != 0); 50 | 51 | return ret; 52 | } 53 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strcspn.c: -------------------------------------------------------------------------------- 1 | /** @file strcspn.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /*- 9 | * Copyright (c) 1990, 1993 10 | * The Regents of the University of California. All rights reserved. 11 | * 12 | * This code is derived from software contributed to Berkeley by 13 | * Chris Torek. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions 17 | * are met: 18 | * 1. Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 2. Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 3. All advertising materials mentioning features or use of this software 24 | * must display the following acknowledgement: 25 | * This product includes software developed by the University of 26 | * California, Berkeley and its contributors. 27 | * 4. Neither the name of the University nor the names of its contributors 28 | * may be used to endorse or promote products derived from this software 29 | * without specific prior written permission. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 32 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 35 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 39 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 40 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 41 | * SUCH DAMAGE. 42 | */ 43 | 44 | #include 45 | 46 | /* 47 | * Span the complement of string s2. 48 | */ 49 | size_t strcspn(const char *s1, const char *s2) 50 | { 51 | const char *p, *spanp; 52 | char c, sc; 53 | 54 | /* 55 | * Stop as soon as we find any character from s2. Note that there 56 | * must be a NUL in s2; it suffices to stop when we find that, too. 57 | */ 58 | for (p = s1;;) { 59 | c = *p++; 60 | spanp = s2; 61 | do { 62 | if ((sc = *spanp++) == c) 63 | return (p - 1 - s1); 64 | } while (sc != 0); 65 | } 66 | /* NOTREACHED */ 67 | } 68 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strlen.c: -------------------------------------------------------------------------------- 1 | /** @file strlen.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | /* 34 | * File: limach/strlen.c 35 | * Author: Robert V. Baron at Carnegie Mellon 36 | * Date: Oct 13, 1992 37 | * Abstract: 38 | * strlen returns the number of characters in "string" preceeding 39 | * the terminating null character. 40 | */ 41 | 42 | #include 43 | 44 | size_t strlen(const char *string) 45 | { 46 | const char *ret = string; 47 | 48 | while (*string++); 49 | 50 | return string - 1 - ret; 51 | } 52 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strncat.c: -------------------------------------------------------------------------------- 1 | /** @file strncat.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /*- 9 | * Copyright (c) 1990, 1993 10 | * The Regents of the University of California. All rights reserved. 11 | * 12 | * This code is derived from software contributed to Berkeley by 13 | * Chris Torek. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions 17 | * are met: 18 | * 1. Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 2. Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 3. All advertising materials mentioning features or use of this software 24 | * must display the following acknowledgement: 25 | * This product includes software developed by the University of 26 | * California, Berkeley and its contributors. 27 | * 4. Neither the name of the University nor the names of its contributors 28 | * may be used to endorse or promote products derived from this software 29 | * without specific prior written permission. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 32 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 35 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 39 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 40 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 41 | * SUCH DAMAGE. 42 | */ 43 | 44 | #include 45 | 46 | /* 47 | * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes 48 | * are written at dst (at most n+1 bytes being appended). Return dst. 49 | */ 50 | char* strncat(char *dst, const char *src, size_t n) 51 | { 52 | if (n != 0) { 53 | char *d = dst; 54 | const char *s = src; 55 | 56 | while (*d != 0) 57 | d++; 58 | do { 59 | if ((*d = *s++) == 0) 60 | break; 61 | d++; 62 | } while (--n != 0); 63 | *d = 0; 64 | } 65 | return (dst); 66 | } 67 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strncmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | int 22 | strncmp(const char *s1, const char *s2, size_t n) 23 | { 24 | while (1) 25 | { 26 | if (n <= 0) 27 | return 0; 28 | if (*s1 != *s2) 29 | return *s1 - *s2; 30 | if (*s1 == 0) 31 | return 0; 32 | 33 | s1++; 34 | s2++; 35 | n--; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strncpy.c: -------------------------------------------------------------------------------- 1 | /** @file strncpy.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Mach Operating System 10 | * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University 11 | * All Rights Reserved. 12 | * 13 | * Permission to use, copy, modify and distribute this software and its 14 | * documentation is hereby granted, provided that both the copyright 15 | * notice and this permission notice appear in all copies of the 16 | * software, derivative works or modified versions, and any portions 17 | * thereof, and that both notices appear in supporting documentation. 18 | * 19 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 20 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 21 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 22 | * 23 | * Carnegie Mellon requests users of this software to return to 24 | * 25 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 26 | * School of Computer Science 27 | * Carnegie Mellon University 28 | * Pittsburgh PA 15213-3890 29 | * 30 | * any improvements or extensions that they make and grant Carnegie Mellon 31 | * the rights to redistribute these changes. 32 | */ 33 | /* 34 | * File: libmach_sa/strncpy.c 35 | * Author: Mary R. Thompson at Carnegie Mellon 36 | * Date: Oct 13, 1992 37 | * Abstract: 38 | * strncpy copies "count" characters from the "from" string to 39 | * the "to" string. If "from" contains less than "count" characters 40 | * "to" will be padded with null characters until exactly "count" 41 | * characters have been written. The return value is a pointer 42 | * to the "to" string. 43 | */ 44 | 45 | #include 46 | 47 | char* strncpy(char *to, const char *from, size_t count) 48 | { 49 | char *ret = to; 50 | 51 | while (count-- > 0 && (*to++ = *from++)); 52 | 53 | while (count-- > 0) 54 | *to++ = '\0'; 55 | 56 | return ret; 57 | } 58 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strpbrk.c: -------------------------------------------------------------------------------- 1 | /** @file strpbrk.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Copyright (c) 1985, 1993 10 | * The Regents of the University of California. All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. All advertising materials mentioning features or use of this software 21 | * must display the following acknowledgement: 22 | * This product includes software developed by the University of 23 | * California, Berkeley and its contributors. 24 | * 4. Neither the name of the University nor the names of its contributors 25 | * may be used to endorse or promote products derived from this software 26 | * without specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 | * SUCH DAMAGE. 39 | */ 40 | 41 | #include 42 | 43 | /* 44 | * Find the first occurrence in s1 of a character in s2 (excluding NUL). 45 | */ 46 | char* strpbrk(const char* s1, const char* s2) 47 | { 48 | const char *scanp; 49 | int c, sc; 50 | 51 | while ((c = *s1++) != 0) { 52 | for (scanp = s2; (sc = *scanp++) != 0;) 53 | if (sc == c) 54 | return ((char *)(s1 - 1)); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strrchr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 The University of Utah and 3 | * the Computer Systems Laboratory at the University of Utah (CSL). 4 | * All rights reserved. 5 | * 6 | * Permission to use, copy, modify and distribute this software is hereby 7 | * granted provided that (1) source code retains these copyright, permission, 8 | * and disclaimer notices, and (2) redistributions including binaries 9 | * reproduce the notices in supporting documentation, and (3) all advertising 10 | * materials mentioning features or use of this software display the following 11 | * acknowledgement: ``This product includes software developed by the 12 | * Computer Systems Laboratory at the University of Utah.'' 13 | * 14 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 15 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 16 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 | * 18 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 19 | * improvements that they make and grant CSL redistribution rights. 20 | */ 21 | 22 | #include 23 | 24 | char* strrchr(const char *s, int c) 25 | { 26 | char *save; 27 | 28 | for (save = 0; *s != '\0'; s++) 29 | if (*s == c) 30 | save = (char *)s; 31 | 32 | return save; 33 | } 34 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strspn.c: -------------------------------------------------------------------------------- 1 | /** @file strspn.c 2 | * 3 | * Modified from 15-410's 410usr library. 4 | * 5 | * @author Kartik Subramanian 6 | * @date 2008-10-30 7 | */ 8 | /* 9 | * Copyright (c) 1989, 1993 10 | * The Regents of the University of California. All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. All advertising materials mentioning features or use of this software 21 | * must display the following acknowledgement: 22 | * This product includes software developed by the University of 23 | * California, Berkeley and its contributors. 24 | * 4. Neither the name of the University nor the names of its contributors 25 | * may be used to endorse or promote products derived from this software 26 | * without specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 | * SUCH DAMAGE. 39 | */ 40 | 41 | #include 42 | 43 | /* 44 | * Span the string s2 (skip characters that are in s2). 45 | */ 46 | size_t strspn(const char *s1, const char *s2) 47 | { 48 | const char *p = s1, *spanp; 49 | char c, sc; 50 | 51 | /* 52 | * Skip any characters in s2, excluding the terminating \0. 53 | */ 54 | cont: 55 | c = *p++; 56 | for (spanp = s2; (sc = *spanp++) != 0;) 57 | if (sc == c) 58 | goto cont; 59 | return (p - 1 - s1); 60 | } 61 | -------------------------------------------------------------------------------- /lab4/tasks/libc/string/strstr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 The University of Utah and 3 | * the Computer Systems Laboratory (CSL). All rights reserved. 4 | * 5 | * Permission to use, copy, modify and distribute this software and its 6 | * documentation is hereby granted, provided that both the copyright 7 | * notice and this permission notice appear in all copies of the 8 | * software, derivative works or modified versions, and any portions 9 | * thereof, and that both notices appear in supporting documentation. 10 | * 11 | * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 12 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 13 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 14 | * 15 | * CSL requests users of this software to return to csl-dist@cs.utah.edu any 16 | * improvements that they make and grant CSL redistribution rights. 17 | */ 18 | 19 | #include 20 | 21 | char *strstr(const char *haystack, const char *needle) 22 | { 23 | int hlen = strlen(haystack); 24 | int nlen = strlen(needle); 25 | 26 | while (hlen >= nlen) 27 | { 28 | if (!memcmp(haystack, needle, nlen)) 29 | return (void*)haystack; 30 | 31 | haystack++; 32 | hlen--; 33 | } 34 | return 0; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/event_wait.S: -------------------------------------------------------------------------------- 1 | /** @file event_wait.S 2 | * 3 | * @brief event wait sycall wrapper 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | #include 11 | #include 12 | 13 | .file "event_wait.S" 14 | 15 | FUNC(event_wait) 16 | swi EVENT_WAIT 17 | 18 | cmp r0, #0 19 | bge return 20 | rsb r0, r0, #0 @r0 = -r0 21 | ldr r1, =errno 22 | str r0, [r1] @set errno = r0 23 | mov r0, #-1 @return -1 24 | 25 | return: 26 | mov pc, lr 27 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/libc.mk: -------------------------------------------------------------------------------- 1 | TLIBC_SWI_OBJS := read.o write.o time.o sleep.o event_wait.o mutex_create.o mutex_unlock.o mutex_lock.o task_create.o 2 | TLIBC_SWI_OBJS := $(TLIBC_SWI_OBJS:%=$(TLIBCDIR)/swi/%) 3 | TLIBC_OBJS += $(TLIBC_SWI_OBJS) 4 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/mutex_create.S: -------------------------------------------------------------------------------- 1 | /** @file mutex_create.S 2 | * 3 | * @brief create mutex sycall wrapper 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | .file "mutex_create.S" 14 | 15 | FUNC(mutex_create) 16 | swi MUTEX_CREATE 17 | 18 | cmp r0, #0 19 | bge return 20 | rsb r0, r0, #0 @r0 = -r0 21 | ldr r1, =errno 22 | str r0, [r1] @set errno = r0 23 | mov r0, #-1 @return -1 24 | 25 | return: 26 | mov pc, lr 27 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/mutex_lock.S: -------------------------------------------------------------------------------- 1 | /** @file mutex_lock.S 2 | * 3 | * @brief acquire mutex sycall wrapper 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | .file "mutex_lock.S" 14 | 15 | FUNC(mutex_lock) 16 | swi MUTEX_LOCK 17 | 18 | cmp r0, #0 19 | bge return 20 | rsb r0, r0, #0 @r0 = -r0 21 | ldr r1, =errno 22 | str r0, [r1] @set errno = r0 23 | mov r0, #-1 @return -1 24 | 25 | return: 26 | mov pc, lr 27 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/mutex_unlock.S: -------------------------------------------------------------------------------- 1 | /** @file mutex_unlock.S 2 | * 3 | * @brief release mutex sycall wrapper 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | .file "mutex_unlock.S" 14 | 15 | FUNC(mutex_unlock) 16 | swi MUTEX_UNLOCK 17 | 18 | cmp r0, #0 19 | bge return 20 | rsb r0, r0, #0 @r0 = -r0 21 | ldr r1, =errno 22 | str r0, [r1] @set errno = r0 23 | mov r0, #-1 @return -1 24 | 25 | return: 26 | mov pc, lr 27 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/read.S: -------------------------------------------------------------------------------- 1 | /** @file read.S 2 | * 3 | * @brief read sycall wrapper 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * 8 | * Date: 2014-11-08 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | .file "read.S" 15 | 16 | .extern errno 17 | 18 | FUNC(read) 19 | swi READ_SWI @args already in r0, r1, r2 20 | 21 | cmp r0, #0 @check return value 22 | bge return 23 | rsb r0, r0, #0 @r0 = -r0 24 | ldr r1, =errno 25 | str r0, [r1] @set errno = r0 26 | mov r0, #-1 @return -1 27 | 28 | return: 29 | mov pc, lr 30 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/sleep.S: -------------------------------------------------------------------------------- 1 | /** @file sleep.S 2 | * 3 | * @brief sleep sycall wrapper 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * 8 | * Date: 2014-11-08 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | .file "sleep.S" 15 | 16 | FUNC(sleep) 17 | swi SLEEP_SWI @args already in r0 18 | 19 | return: 20 | mov pc, lr 21 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/task_create.S: -------------------------------------------------------------------------------- 1 | /** @file task_create.S 2 | * 3 | * @brief task create sycall wrapper 4 | * 5 | * @author Qinyu Tong 6 | * HuaCong Cai 7 | * 8 | * @date Tue Nov 25 15:23:08 EST 2014 9 | */ 10 | 11 | #include 12 | #include 13 | .file "task_create.S" 14 | 15 | FUNC(task_create) 16 | swi CREATE_SWI 17 | 18 | rsb r0, r0, #0 @r0 = -r0 19 | ldr r1, =errno 20 | str r0, [r1] @set errno = r0 21 | mov r0, #-1 @return -1 22 | 23 | return: 24 | mov pc, lr 25 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/time.S: -------------------------------------------------------------------------------- 1 | /** @file time.S 2 | * 3 | * @brief time sycall wrapper 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * 8 | * Date: 2014-11-08 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | .file "time.S" 15 | 16 | FUNC(time) 17 | swi TIME_SWI @return value already in r0 18 | 19 | return: 20 | mov pc, lr 21 | -------------------------------------------------------------------------------- /lab4/tasks/libc/swi/write.S: -------------------------------------------------------------------------------- 1 | /** @file write.S 2 | * 3 | * @brief write sycall wrapper 4 | * 5 | * Author: Huacong Cai 6 | * Qingyu Tong 7 | * 8 | * Date: 2014-11-08 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | .file "write.S" 15 | 16 | .extern errno 17 | 18 | FUNC(write) 19 | swi WRITE_SWI @args already in r0, r1, r2 20 | 21 | cmp r0, #0 @check return value 22 | bge return 23 | rsb r0, r0, #0 @r0 = -r0 24 | ldr r1, =errno 25 | str r0, [r1] @set errno = r0 26 | mov r0, #-1 @return -1 27 | 28 | return: 29 | mov pc, lr 30 | -------------------------------------------------------------------------------- /lab4/tasks/mutex_chaser/mutex_chaser.c: -------------------------------------------------------------------------------- 1 | /** @file mutex_chaser.c 2 | * 3 | * @brief A test to aggresively acquire/release the maximum number of mutexes. 4 | * Each mutex has a corresponding number and each task performs a certain operation on a mutex's 5 | * number after it acquires a lock on it. After each task has acquire/release a mutex, simple 6 | * check if the number is consistent with the correct value. 7 | * The mutex they are implementing is more like a conditional variable that has a FIFO sleep queue. 8 | * 9 | * Purpose of the test: 10 | * 1.Ensure mutex is releasing task in FCFS order. 11 | * 2.Make sure rate monotonic scheduling is preserved. 12 | * 13 | * 14 | * @author Kevin Chang(kevincha) 15 | * @data 2010-12-01 16 | **/ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define MUTEX_NUM 32 25 | #define YES_STR "\033[32;1mYes!\033[0m\n" 26 | #define NO_STR "\033[31;1mNo!\033[0m\n" 27 | #define TEST_DONE "\033[32;1mTEST PASSED SUCCESSFULLY!\033[0m\n" 28 | 29 | //order of operations: ((init_val+3)*11-7)*13=61 30 | static int fun1_opval=3; 31 | static int fun2_opval=11; 32 | static int fun3_opval=7; 33 | static int fun4_opval=13; 34 | static int init_val=2; 35 | static int result_val=0; 36 | 37 | int mutex_val[MUTEX_NUM]; 38 | 39 | void panic(const char* str) 40 | { 41 | puts(str); 42 | while(1); 43 | } 44 | //dev3 45 | void fun1(void* str) 46 | { 47 | int cur_mutex=1; 48 | str = str; 49 | while(cur_mutex>mutex %d\n",cur_mutex); 52 | if(mutex_lock(cur_mutex)) 53 | panic("Failed to acquire mutex"); 54 | mutex_val[cur_mutex]=mutex_val[cur_mutex]+fun1_opval; 55 | if(mutex_unlock(cur_mutex)) 56 | { 57 | if(errno==EINVAL) 58 | puts("EINVAL"); 59 | if(errno==EPERM) 60 | puts("EPERM"); 61 | panic("Failed to release mutex"); 62 | } 63 | cur_mutex++; 64 | if (event_wait(3) < 0) 65 | panic("Dev 3 failed"); 66 | } 67 | while(1) 68 | if (event_wait(3) < 0) 69 | panic("Dev 3 failed"); 70 | } 71 | //dev0 72 | void fun2(void* str) 73 | { 74 | int cur_mutex=1; 75 | 76 | str = str; 77 | while(cur_mutex>mutex %d\n",cur_mutex); 80 | if(mutex_lock(cur_mutex)) 81 | panic("Failed to acquire mutex"); 82 | mutex_val[cur_mutex]=mutex_val[cur_mutex]*fun2_opval; 83 | if(mutex_unlock(cur_mutex)) 84 | panic("Failed to release mutex"); 85 | cur_mutex++; 86 | if (event_wait(0) < 0) 87 | panic("Dev 0 failed"); 88 | } 89 | while(1) 90 | if (event_wait(0) < 0) 91 | panic("Dev 0 failed"); 92 | } 93 | //dev1 94 | void fun3(void* str) 95 | { 96 | int cur_mutex=1; 97 | 98 | str = str; 99 | while(cur_mutex>mutex %d\n",cur_mutex); 102 | if(mutex_lock(cur_mutex)) 103 | panic("Failed to acquire mutex"); 104 | mutex_val[cur_mutex]=mutex_val[cur_mutex]-fun3_opval; 105 | if(mutex_unlock(cur_mutex)) 106 | panic("Failed to release mutex"); 107 | cur_mutex++; 108 | if (event_wait(1) < 0) 109 | panic("Dev 1 failed"); 110 | } 111 | while(1) 112 | if (event_wait(1) < 0) 113 | panic("Dev 1 failed"); 114 | } 115 | //dev2 116 | void fun4(void* str) 117 | { 118 | int cur_mutex=1,i=0,m_val; 119 | 120 | str = str; 121 | while(cur_mutex>mutex %d\n",cur_mutex); 124 | if(mutex_lock(cur_mutex)) 125 | panic("Failed to acquire mutex"); 126 | mutex_val[cur_mutex]=mutex_val[cur_mutex]*fun4_opval; 127 | if(mutex_unlock(cur_mutex)) 128 | panic("Failed to release mutex"); 129 | cur_mutex++; 130 | if (event_wait(2) < 0) 131 | panic("Dev 2 failed"); 132 | } 133 | for(;i 13 | #include 14 | #include 15 | #include 16 | 17 | int even_t1 = 1; 18 | int once = 0; 19 | int even_t2 = 1; 20 | int even_t3 = 1; 21 | volatile int mid = -1; 22 | 23 | void panic(const char* str) 24 | { 25 | puts(str); 26 | while(1); 27 | } 28 | 29 | void fun1(void* str) 30 | { 31 | // On first pass, create the shared mutex 32 | mid = mutex_create(); 33 | while(1) { 34 | if(even_t1) { 35 | // first and last s 36 | putchar((int)str); 37 | // terminating 38 | if(once >0) { 39 | putchar((int)'!'); 40 | while(1) mid++; 41 | } 42 | once = 1; 43 | even_t1 = 0; 44 | } 45 | else { 46 | // should not succeed right away 47 | mutex_lock(mid); 48 | // prints e 49 | putchar((int)'e'); 50 | even_t1 = 1; 51 | mutex_unlock(mid); 52 | } 53 | if (event_wait(0) < 0) { 54 | panic("Dev 0 failed"); 55 | } 56 | } 57 | } 58 | 59 | void fun2(void* str) 60 | { 61 | while(1) 62 | { 63 | if(even_t2) { 64 | // prints u 65 | putchar((int)str); 66 | even_t2 = 0; 67 | } 68 | else { 69 | // should not succeed right away 70 | mutex_lock(mid); 71 | // prints s! 72 | putchar((int)'S'); 73 | } 74 | if (event_wait(1) < 0) 75 | panic("Dev 1 failed"); 76 | } 77 | } 78 | 79 | void fun3(void* str) 80 | { 81 | while(1) 82 | { 83 | //c 84 | putchar((int)str); 85 | if(even_t3) { 86 | // should succeed 87 | mutex_lock(mid); 88 | even_t3 = 0; 89 | } else { 90 | mutex_unlock(mid); 91 | } 92 | if (event_wait(2) < 0) 93 | panic("Dev 2 failed"); 94 | } 95 | } 96 | int main(int argc, char** argv) 97 | { 98 | task_t tasks[3]; 99 | tasks[0].lambda = fun1; 100 | tasks[0].data = (void*)'s'; 101 | tasks[0].stack_pos = (void*)0xa2000000; 102 | tasks[0].C = 1; 103 | tasks[0].T = PERIOD_DEV0; 104 | tasks[1].lambda = fun2; 105 | tasks[1].data = (void*)'u'; 106 | tasks[1].stack_pos = (void*)0xa1000000; 107 | tasks[1].C = 1; 108 | tasks[1].T = PERIOD_DEV1; 109 | tasks[2].lambda = fun3; 110 | tasks[2].data = (void*)'c'; 111 | tasks[2].stack_pos = (void*)0xa1200000; 112 | tasks[2].C = 1; 113 | tasks[2].T = PERIOD_DEV2; 114 | task_create(tasks, 3); 115 | // just to get rid of compiler... 116 | argc = argc; 117 | argv = argv; 118 | puts("WTF!\n"); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /lab4/tasks/simple_mutex/simple_mutex.dep: -------------------------------------------------------------------------------- 1 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/simple_mutex/simple_mutex.o: \ 2 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/simple_mutex/simple_mutex.c \ 3 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/stdio.h \ 4 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/stdarg.h \ 5 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/sys/types.h \ 6 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/bits/types.h \ 7 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/unistd.h \ 8 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/bits/fileno.h \ 9 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/task.h \ 10 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/lock.h 11 | 12 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/stdio.h: 13 | 14 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/stdarg.h: 15 | 16 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/sys/types.h: 17 | 18 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/bits/types.h: 19 | 20 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/unistd.h: 21 | 22 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/bits/fileno.h: 23 | 24 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/task.h: 25 | 26 | /afs/ece/usr/taoy/TA/349TA/lab4_cmar/tasks/libc/include/lock.h: 27 | -------------------------------------------------------------------------------- /lab4/tasks/skyeye.conf: -------------------------------------------------------------------------------- 1 | cpu: pxa25x 2 | mach: pxa_lubbock 3 | mem_bank: map=M, type=R, addr=0x00000000, size=0x0400000, file=../u-boot.bin, boot=yes 4 | mem_bank: map=I, type=RW, addr=0x40000000, size=0x0c000000 5 | mem_bank: map=M, type=RW, addr=0xa0000000, size=0x03000000, file=./package.bin 6 | mem_bank: map=M, type=RW, addr=0xa3000000, size=0x0e000000, file=../../kernel/kernel.bin 7 | #log: logon=1, logfile=/tmp/sk2.log, start=500000, end=1500000 8 | #lcd:state=on,type=pxa,mod=gtk 9 | 10 | #dbct:state=on 11 | -------------------------------------------------------------------------------- /lab4/tasks/stress/.stress.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironAtom/RTOS-Kernel-for-ARM/1bc031ace5e9054236e3a54781382bc34f364c69/lab4/tasks/stress/.stress.c.swp -------------------------------------------------------------------------------- /lab4/tasks/stress/pack.mk: -------------------------------------------------------------------------------- 1 | PROGS_STRESS_OBJS := stress.o 2 | PROGS_STRESS_OBJS := $(PROGS_STRESS_OBJS:%=$(TDIR)/stress/%) 3 | ALL_OBJS += $(PROGS_STRESS_OBJS) 4 | 5 | $(TDIR)/bin/stress : $(TSTART) $(PROGS_STRESS_OBJS) $(TLIBC) 6 | 7 | -------------------------------------------------------------------------------- /lab4/tasks/stress/stress.c: -------------------------------------------------------------------------------- 1 | /** @file stress.c 2 | * 3 | * @brief Creates 60 periodic tasks,each with diff frequency 4 | * 5 | * This is just a stress test, to ensure no concurrency bugs 6 | * 7 | * @author Tao Yang(taoy) 8 | * @date 2010-12-7 9 | */ 10 | #include 11 | #include 12 | #include 13 | 14 | #define NUM_TASK 60 15 | #define END_TIME 9000 16 | #define NUM_ITER 2 17 | int once; 18 | int flag; 19 | int score[NUM_TASK-1]; 20 | void panic(const char* str) 21 | { 22 | puts(str); 23 | while(1); 24 | } 25 | 26 | void fun1(void* str) 27 | { 28 | while(1) 29 | { 30 | if(flag == 0) { 31 | printf("Time is now %lu\n",time()); 32 | } 33 | score[(int)str]++; 34 | sleep((int)str); 35 | if (event_wait((int)str) < 0) 36 | panic("Dev 0 failed"); 37 | } 38 | } 39 | 40 | void fun2(void* str) 41 | { 42 | int i; 43 | while(1) 44 | { 45 | if(once < NUM_ITER) { 46 | once++; 47 | puts("One more time"); 48 | } 49 | else { 50 | // check RMA 51 | for(i=0;i<(NUM_TASK-2);i++) { 52 | if(score[i] < score[i+1]) { 53 | printf("RMA check failed on %d\n",i); 54 | puts("xxxxxxxxxx Test FAIL xxxxxxxx"); 55 | } 56 | if(score[i] == 0) { 57 | printf("Task %d never executed?\n",i); 58 | puts("xxxxxxxxxx Test FAIL xxxxxxxxx"); 59 | } 60 | } 61 | puts("*********** Test PASEED *******************"); 62 | flag = 1; 63 | } 64 | if (event_wait((int)str) < 0) 65 | panic("Dev 0 failed"); 66 | } 67 | } 68 | 69 | int main(int argc, char** argv) 70 | { 71 | puts("Test begins"); 72 | int i; 73 | task_t tasks[NUM_TASK]; 74 | once = 0; 75 | flag = 0; 76 | for(i=0;i<(NUM_TASK-1);i++) { 77 | tasks[i].lambda = fun1; 78 | tasks[i].data = (void*)i; 79 | tasks[i].stack_pos = (void*)(0xa2000000 + 0x10000 * i); 80 | tasks[i].C = (i+1); 81 | tasks[i].T = (i+1)*100; 82 | score[i] = 0; 83 | } 84 | tasks[i].lambda = fun2; 85 | tasks[i].data = (void*)i; 86 | tasks[i].stack_pos = (void*)(0xa2000000 + 0x10000 * i); 87 | tasks[i].C = 0; 88 | tasks[i].T = END_TIME; 89 | task_create(tasks, NUM_TASK); 90 | argc=argc; /* remove compiler warning */ 91 | argv=argv; /* remove compiler warning */ 92 | 93 | puts("Elvis could not leave the building, but why did your code get here!\n"); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /lab4/tasks/sys_err/pack.mk: -------------------------------------------------------------------------------- 1 | PROGS_DAGGER_OBJS := sys_err.o 2 | PROGS_DAGGER_OBJS := $(PROGS_DAGGER_OBJS:%=$(TDIR)/sys_err/%) 3 | ALL_OBJS += $(PROGS_DAGGER_OBJS) 4 | 5 | $(TDIR)/bin/sys_err : $(TSTART) $(PROGS_DAGGER_OBJS) $(TLIBC) 6 | 7 | -------------------------------------------------------------------------------- /lab4/tasks/sys_err/sys_err.c: -------------------------------------------------------------------------------- 1 | /** @file sys_err.c 2 | * 3 | * @brief 1. Tests task_create return EINVAL and EFAULT 4 | * 2. Tests mutex lock return EINVAL and EDEADLOCK 5 | * 3. Tests unlock return EINVAL and EPERM 6 | * 4. Tests device returning EINVAL 7 | * 5. Tests mutex create returning ENOMEM 8 | * 9 | * @author Tao Yang(taoy) 10 | * @date 2010-11-30 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define MAX_MUTEX 32 // check this 20 | volatile int spin = 0; 21 | void check_return(int r,int expected,const char *str); 22 | void report_suc(const char *str); 23 | void report_fail(const char *str); 24 | 25 | void fun1(void* str) 26 | { 27 | int ret2,i,ind; 28 | str = str; 29 | for(i=0 ;i 7 | #include 8 | 9 | /* From common.h: */ 10 | typedef void (interrupt_handler_t)(void *); 11 | 12 | /* These are declarations of exported functions available in C code */ 13 | unsigned long get_version(void); 14 | int getc(void); 15 | int tstc(void); 16 | void putc(const char); 17 | void puts(const char*) __attribute__((nonnull)); 18 | void printf(const char* fmt, ...) __attribute__((nonnull (1), format (printf, 1, 2))); 19 | void install_hdlr(int, interrupt_handler_t*, void*); 20 | void free_hdlr(int); 21 | void *malloc(size_t); 22 | void free(void*); 23 | void udelay(unsigned long); 24 | unsigned long get_timer(unsigned long); 25 | void vprintf(const char *, va_list) __attribute__((nonnull)); 26 | void do_reset (void) __attribute__((noreturn)); 27 | unsigned long simple_strtoul(const char*, char**, unsigned int) __attribute__((const, nonnull)); 28 | char* getenv (char*) __attribute__((nonnull)); 29 | void setenv (char*, char*) __attribute__((nonnull)); 30 | 31 | void app_startup(void); 32 | 33 | enum { 34 | #define EXPORT_FUNC(x) XF_ ## x , 35 | #include <_exports.h> 36 | #undef EXPORT_FUNC 37 | 38 | XF_MAX 39 | }; 40 | 41 | #define XF_VERSION 2 42 | 43 | #endif /* _EXPORTS_H_ */ 44 | -------------------------------------------------------------------------------- /lab4/uboot/stubs.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stub.c 3 | * 4 | * @brief U-Boot standalone API entry stubs. 5 | * 6 | * This file generate assembly stubs that act as a shim-layer between the 7 | * kernel and u-boot's standalone API routines. 8 | * 9 | * @author Mike Kasick 10 | * 11 | * Modified from u-boot-1.1.4/examples/stubs.c 12 | */ 13 | 14 | #include 15 | 16 | /* offsetof(gd_t, jt) */ 17 | #define OFFSETOF_JT_IN_GD_T 32 18 | 19 | /* 20 | * r8 holds the pointer to the global_data, ip is a call-clobbered 21 | * register 22 | */ 23 | #define EXPORT_FUNC(x) \ 24 | asm volatile ( \ 25 | " .globl " #x "\n" \ 26 | #x ":\n" \ 27 | " ldr ip, [r8, %0]\n" \ 28 | " ldr pc, [ip, %1]\n" \ 29 | : : "i"(OFFSETOF_JT_IN_GD_T), "i"(XF_ ## x * sizeof(void *)) : "ip"); 30 | 31 | /* This function is necessary to prevent the compiler from 32 | * generating prologue/epilogue, preparing stack frame etc. 33 | * The stub functions are special, they do not use the stack 34 | * frame passed to them, but pass it intact to the actual 35 | * implementation. On the other hand, asm() statements with 36 | * arguments can be used only inside the functions (gcc limitation) 37 | */ 38 | static void __attribute__((used, naked)) dummy(void) 39 | { 40 | #include <_exports.h> 41 | } 42 | 43 | extern unsigned long __bss_start, _end; 44 | 45 | void app_startup(void) 46 | { 47 | unsigned long * cp = &__bss_start; 48 | 49 | /* Zero out BSS */ 50 | while (cp < &_end) { 51 | *cp++ = 0; 52 | } 53 | } 54 | 55 | #undef EXPORT_FUNC 56 | -------------------------------------------------------------------------------- /lab4/uboot/uboot.mk: -------------------------------------------------------------------------------- 1 | UOBJS := stubs.o 2 | UOBJS := $(UOBJS:%=$(UDIR)/%) 3 | ALL_OBJS += $(UOBJS) 4 | 5 | --------------------------------------------------------------------------------