diff options
author | Jakob Odersky <jodersky@gmail.com> | 2014-04-08 13:18:27 +0200 |
---|---|---|
committer | Jakob Odersky <jodersky@gmail.com> | 2014-04-08 14:57:10 +0200 |
commit | 350437ef4b8ba0811d285f7454d2b54ffce6b029 (patch) | |
tree | 5084c73adbb4cc3aee9d000b3816d98a57203f36 /kernel/include/mux | |
parent | c4ebb91caf33ecf5a47785584a4231eb1e4dfa2a (diff) | |
download | mux-350437ef4b8ba0811d285f7454d2b54ffce6b029.tar.gz mux-350437ef4b8ba0811d285f7454d2b54ffce6b029.tar.bz2 mux-350437ef4b8ba0811d285f7454d2b54ffce6b029.zip |
change build structure
Diffstat (limited to 'kernel/include/mux')
-rw-r--r-- | kernel/include/mux/clock.h | 21 | ||||
-rw-r--r-- | kernel/include/mux/debug.h | 7 | ||||
-rw-r--r-- | kernel/include/mux/idle.h | 6 | ||||
-rw-r--r-- | kernel/include/mux/io.h | 30 | ||||
-rw-r--r-- | kernel/include/mux/list.h | 244 | ||||
-rw-r--r-- | kernel/include/mux/lock.h | 24 | ||||
-rw-r--r-- | kernel/include/mux/rbuffer.h | 48 | ||||
-rw-r--r-- | kernel/include/mux/sched.h | 101 |
8 files changed, 481 insertions, 0 deletions
diff --git a/kernel/include/mux/clock.h b/kernel/include/mux/clock.h new file mode 100644 index 0000000..429a00d --- /dev/null +++ b/kernel/include/mux/clock.h @@ -0,0 +1,21 @@ +#ifndef MUX_CLOCK_H +#define MUX_CLOCK_H + +/** + * Initializes main system clock. + * @ms time between each tick in milliseconds + * @tick function to run every tick + */ +void clock_init(int ms, void (*tick)()); + +/** + * Starts main system clock. + */ +void clock_start(); + +/** + * Stops main system clock. + */ +void clock_stop(); + +#endif
\ No newline at end of file diff --git a/kernel/include/mux/debug.h b/kernel/include/mux/debug.h new file mode 100644 index 0000000..7119c35 --- /dev/null +++ b/kernel/include/mux/debug.h @@ -0,0 +1,7 @@ +#ifndef MUX_DEBUG_H +#define MUX_DEBUG_H + +void panic(); +void debug_led(int led, int value); + +#endif
\ No newline at end of file diff --git a/kernel/include/mux/idle.h b/kernel/include/mux/idle.h new file mode 100644 index 0000000..0d94a9a --- /dev/null +++ b/kernel/include/mux/idle.h @@ -0,0 +1,6 @@ +#ifndef MUX_IDLE_H +#define MUX_IDLE_H + +void idle_entry(char args); + +#endif
\ No newline at end of file diff --git a/kernel/include/mux/io.h b/kernel/include/mux/io.h new file mode 100644 index 0000000..4ec45f5 --- /dev/null +++ b/kernel/include/mux/io.h @@ -0,0 +1,30 @@ +#ifndef MUX_IO_H +#define MUX_IO_H + +#include <stddef.h> + +typedef long ssize_t; + +struct file; +struct file_operations; + +struct file { + struct file_operations* const fops; + void* private_data; +}; + +struct file_operations { + int (*open)(struct file* file); + int (*ioctl)(struct file* file, int cmd, long args); + ssize_t (*read)(struct file* file, char* const buffer, size_t size); + ssize_t (*write)(struct file* file, const char* const buffer, size_t size); + int (*close)(struct file* file); +}; + +int open(struct file* file); +int ioctl(struct file* file, int cmd, long args); +ssize_t read(struct file* file, char* const buffer, size_t size); +ssize_t write(struct file* file, const char* const buffer, size_t size); +int close(struct file* file); + +#endif
\ No newline at end of file diff --git a/kernel/include/mux/list.h b/kernel/include/mux/list.h new file mode 100644 index 0000000..98ea766 --- /dev/null +++ b/kernel/include/mux/list.h @@ -0,0 +1,244 @@ +#ifndef MUX_LIST_H +#define MUX_LIST_H + +/* This file is from Linux Kernel (include/linux/list.h) + * and modified by simply removing hardware prefetching of list items. + * Here by copyright, credits attributed to wherever they belong. + * Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu) + */ + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = (void *) 0; + entry->prev = (void *) 0; +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + + +#endif diff --git a/kernel/include/mux/lock.h b/kernel/include/mux/lock.h new file mode 100644 index 0000000..b5ac4d9 --- /dev/null +++ b/kernel/include/mux/lock.h @@ -0,0 +1,24 @@ +#ifndef MUX_LOCK_H +#define MUX_LOCK_H + +#include "mux/sched.h" + +typedef volatile char spin_lock_t; + +#define SPIN_LOCK_UNLOCKED 0 +#define SPIN_LOCK_LOCKED 0 + +static inline void spin_lock(spin_lock_t* lock) { + while(*lock != SPIN_LOCK_UNLOCKED) {yield();}; + cli(); + *lock = SPIN_LOCK_LOCKED; + sei(); +} + +static inline void spin_unlock(spin_lock_t* lock) { + cli(); + *lock = SPIN_LOCK_UNLOCKED; + sei(); +} + +#endif
\ No newline at end of file diff --git a/kernel/include/mux/rbuffer.h b/kernel/include/mux/rbuffer.h new file mode 100644 index 0000000..dceaeb0 --- /dev/null +++ b/kernel/include/mux/rbuffer.h @@ -0,0 +1,48 @@ +#ifndef RBUFFER_H +#define RBUFFER_H + +#include <stddef.h> + +struct rbuffer_t { + char* address_begin; + char* address_end; + char* volatile head; + char* volatile tail; +}; + +#define RBUFFER_INIT(array, length) \ + { \ + .address_begin = array, \ + .address_end = array + length, \ + .head = array, \ + .tail = array \ + } + +#define INIT_RBUFFER(buffer, array, length) \ + (buffer)->address_begin = (array); \ + (buffer)->address_end = (array) + (length); \ + (buffer)->head = (array); \ + (buffer)->tail = (array) + +static inline int rbuffer_empty(struct rbuffer_t* const rb) { + return rb->head == rb->tail; +} + +static inline int rbuffer_write(struct rbuffer_t* const rb, char data) { + char* next_head = rb->head + 1; + if(next_head >= rb->address_end) next_head = rb->address_begin; + if (rb->tail == next_head) return -1; + *rb->head = data; + rb->head = next_head; + return 0; +} + +static inline int rbuffer_read(struct rbuffer_t* const rb, char* const data) { + if (rbuffer_empty(rb)) return -1; + *data = *rb->tail; + rb->tail += 1; + if(rb->tail >= rb->address_end) rb->tail = rb->address_begin; + return 0; +} + +#endif diff --git a/kernel/include/mux/sched.h b/kernel/include/mux/sched.h new file mode 100644 index 0000000..de50f98 --- /dev/null +++ b/kernel/include/mux/sched.h @@ -0,0 +1,101 @@ +#ifndef MUX_SCHED_H +#define MUX_SCHED_H + +#include "mux/list.h" + +/** + * Task control block, contains runtime + * information about tasks. + */ +struct tcb_t { + /** Stack pointer of this task. (must be first in structure) */ + char* volatile sp; + + /** Lowest address of this task's memory (inclusive). */ + char* mem_low; + + /** Highest address of this task's memory (inclusive). */ + char* mem_high; + + /** Entry function of this task. */ + void (*entry)(char); + + /** Current wait queue that this task is in.*/ + struct list_head queue; + + /** ID of task. */ + char id; + +}; + +/** + * Utility for declaring a task with statically allocated memory. + * Note: for a task to be scheduled, it must first be spawned (see spawn()). +*/ +#define DECLARE_TASK(name, stack_size, entry_function) \ + static char _declared_stack_##name[stack_size]; \ + static struct tcb_t name = { \ + .sp = 0, \ + .mem_low = _declared_stack_##name, \ + .mem_high = _declared_stack_##name + stack_size - 1, \ + .entry = entry_function, \ + .queue = {} \ + }; + + +/** + * Points to currently executing task. If no scheduling has been enabled, + * this points to NULL + */ +extern struct tcb_t* volatile current; + +/** + * Queue that contains all tasks that are ready to be run, awaiting their + * turn from the scheduler. + */ +extern struct list_head ready; + +/** + * Makes the current task sleep on a specific queue. + * This moves the current task to the given queue's tail. + */ +static inline void sleep_queue(struct list_head* queue) { + list_move_tail(¤t->queue, queue); +} + +/** + * Wakes all tasks waiting in the given queue. + * This moves all tasks contained in the queue to the ready queue. + */ +static inline void wake_all_queue(struct list_head* queue) { + list_splice_init(queue, ready.prev); +} + +/** + * Initializes a given task and adds it to the ready queue. + */ +void spawn(struct tcb_t* const tcb, char id); + +/** + * Spawns the idle task + */ +void spawn_idle(struct tcb_t* const tcb, char id); + +/** + * Voluntarily relinquishes control of the CPU from the current task to the scheduler. + */ +void yield() __attribute__ ( ( naked ) ); + + +/** + * Initializes the scheduler by setting up kstack, initializing the idle task + * and selecting the first task to run. + */ +void sched_init(); + +/** + * Enters the scheduler, setting current to the next runnable task. + */ +void schedule(); + +#endif |