# HG changeset patch # User Paul Boddie # Date 1461428378 -7200 # Node ID e572b72b9a83a7e5a3a8e601ad3c128c283c72aa # Parent 134efe2c5a9f4f85c82bf79e227d06671f4dcb8e Moved the task management and the example task into separate files. diff -r 134efe2c5a9f -r e572b72b9a83 stage2/Makefile --- a/stage2/Makefile Sat Apr 23 17:26:50 2016 +0200 +++ b/stage2/Makefile Sat Apr 23 18:19:38 2016 +0200 @@ -62,8 +62,8 @@ # Ordering of objects is important and cannot be left to replacement rules. -SRC = head2.S entry.S handlers.S stage2.c cpu.c lcd.c jzlcd.c board.c irq.c $(BOARD_SRC) -OBJ = head2.o entry.o handlers.o stage2.o cpu.o lcd.o jzlcd.o board.o irq.o $(BOARD_OBJ) +SRC = head2.S entry.S handlers.S stage2.c cpu.c lcd.c jzlcd.c board.c irq.c tasks.c example.c $(BOARD_SRC) +OBJ = head2.o entry.o handlers.o stage2.o cpu.o lcd.o jzlcd.o board.o irq.o tasks.o example.o $(BOARD_OBJ) .PHONY: all clean distclean diff -r 134efe2c5a9f -r e572b72b9a83 stage2/example.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/example.c Sat Apr 23 18:19:38 2016 +0200 @@ -0,0 +1,57 @@ +/* + * Example tasks. + * + * Copyright (C) 2015, 2016 Paul Boddie + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "board.h" +#include "lcd.h" +#include "jzlcd.h" +#include "tasks.h" + +extern vidinfo_t panel_info; + +void next_pixel(unsigned short *x, unsigned short *y) +{ + (*x)++; + if (*x >= panel_info.vl_col) { + *x = 0; + (*y)++; + if (*y >= panel_info.vl_row) + *y = 0; + } +} + +/* Tasks. */ + +void plot_pattern(unsigned short pixel_type, unsigned short x, unsigned short y) +{ + while (1) { + if (pixel_type) + test_pixel(x, y, pixel_type); + else + clear_pixel(x, y); + next_pixel(&x, &y); + udelay(100); + } +} + +void start_plot_pattern(unsigned short task) +{ + u32 args[] = {task, 0, (task - 1) * 60}; + + start_task(task, (void (*)()) plot_pattern, args, 3); +} diff -r 134efe2c5a9f -r e572b72b9a83 stage2/example.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/example.h Sat Apr 23 18:19:38 2016 +0200 @@ -0,0 +1,9 @@ +#ifndef __EXAMPLE_H__ +#define __EXAMPLE_H__ + +/* Example task functions. */ + +void plot_pattern(unsigned short, unsigned short, unsigned short); +void start_plot_pattern(unsigned short); + +#endif /* __EXAMPLE_H__ */ diff -r 134efe2c5a9f -r e572b72b9a83 stage2/irq.c --- a/stage2/irq.c Sat Apr 23 17:26:50 2016 +0200 +++ b/stage2/irq.c Sat Apr 23 18:19:38 2016 +0200 @@ -21,54 +21,9 @@ #include "init.h" #include "board.h" -#include "lcd.h" -#include "jzlcd.h" #include "cpu.h" -#include "paging.h" #include "irq.h" - -extern vidinfo_t panel_info; - -void next_pixel(unsigned short *x, unsigned short *y) -{ - (*x)++; - if (*x >= panel_info.vl_col) { - *x = 0; - (*y)++; - if (*y >= panel_info.vl_row) - *y = 0; - } -} - -/* Task management. */ - -enum { max_tasks = 3 }; -static u32 stack_pointers[max_tasks]; -static u32 registers[max_tasks][32]; - -u8 current_task; -u32 *current_stack_pointer; -u32 *current_registers; - -extern u32 _got_copy_start; - -const u32 stack_start = 0x00080000; -const u32 stack_size = 0x00002000; -const u32 pagesize = 4 * 1024; - -/* Tasks. */ - -void plot_pattern(unsigned short pixel_type, unsigned short x, unsigned short y) -{ - while (1) { - if (pixel_type) - test_pixel(x, y, pixel_type); - else - clear_pixel(x, y); - next_pixel(&x, &y); - udelay(100); - } -} +#include "tasks.h" /* Initialisation and handling. */ @@ -104,48 +59,3 @@ } } } - -void init_tasks() -{ - current_task = 0; - current_stack_pointer = &stack_pointers[current_task]; - current_registers = registers[current_task]; -} - -void start_task(unsigned short task) -{ - u32 args[] = {task, 0, (task - 1) * 60}; - u32 virtual, physical; - - /* - Each task employs a stack at a multiple of the given start address in - physical memory, but at the same address in virtual memory. - */ - - virtual = stack_start; - physical = stack_start - stack_size * task; - - init_page_table(page_table_start, virtual - pagesize * 2, physical - pagesize * 2, pagesize, 0x1e, task); - - stack_pointers[task] = virtual - 12; - - /* - Set the registers for the new task, initialising the global pointer and - return address. - */ - - init_registers(registers[task], _got_copy_start, (void (*)()) plot_pattern, args, 3); -} - -void switch_task() -{ - /* Switch the current task. */ - - current_task++; - if (current_task == max_tasks) current_task = 0; - - /* Indicate the current stack pointer and task registers. */ - - current_stack_pointer = &stack_pointers[current_task]; - current_registers = registers[current_task]; -} diff -r 134efe2c5a9f -r e572b72b9a83 stage2/irq.h --- a/stage2/irq.h Sat Apr 23 17:26:50 2016 +0200 +++ b/stage2/irq.h Sat Apr 23 18:19:38 2016 +0200 @@ -4,9 +4,5 @@ /* Initialisation functions. */ void irq_init(void); -void init_tasks(void); -void start_task(unsigned short); -void switch_task(void); -void plot_pattern(unsigned short, unsigned short, unsigned short); #endif /* __IRQ_H__ */ diff -r 134efe2c5a9f -r e572b72b9a83 stage2/stage2.c --- a/stage2/stage2.c Sat Apr 23 17:26:50 2016 +0200 +++ b/stage2/stage2.c Sat Apr 23 18:19:38 2016 +0200 @@ -22,6 +22,8 @@ #include "irq.h" #include "lcd.h" #include "cpu.h" +#include "tasks.h" +#include "example.h" void c_main(void) { @@ -48,8 +50,8 @@ /* Start the tasks. */ init_tasks(); - start_task(1); - start_task(2); + start_plot_pattern(1); + start_plot_pattern(2); /* Now, wait for the tasks to be selected as interrupts occur. */ diff -r 134efe2c5a9f -r e572b72b9a83 stage2/tasks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/tasks.c Sat Apr 23 18:19:38 2016 +0200 @@ -0,0 +1,92 @@ +/* + * Task handling. + * + * Copyright (C) 2015, 2016 Paul Boddie + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "cpu.h" +#include "paging.h" + +/* Task tables and data. */ + +enum { max_tasks = 3 }; +static u32 stack_pointers[max_tasks]; +static u32 registers[max_tasks][32]; + +u8 current_task; +u32 *current_stack_pointer; +u32 *current_registers; + +/* Address locations and paging configuration. */ + +const u32 stack_start = 0x00080000; +const u32 stack_size = 0x00002000; +const u32 pagesize = 4 * 1024; + +/* The unrelocated symbol table location. */ + +extern u32 _got_copy_start; + +/* Task management functions. */ + +void init_tasks() +{ + current_task = 0; + current_stack_pointer = &stack_pointers[current_task]; + current_registers = registers[current_task]; +} + +void start_task(unsigned short task, void (*function)(), u32 args[], unsigned short nargs) +{ + u32 virtual, physical; + + /* + Each task employs a stack at a multiple of the given start address in + physical memory, but at the same address in virtual memory. + */ + + virtual = stack_start; + physical = stack_start - stack_size * task; + + init_page_table(page_table_start, virtual - pagesize * 2, physical - pagesize * 2, pagesize, 0x1e, task); + + /* + Subtract from the stack pointer to prevent the called function from + reaching into unmapped memory. + */ + + stack_pointers[task] = virtual - 12; + + /* + Set the registers for the new task, initialising the global pointer and + return address. + */ + + init_registers(registers[task], _got_copy_start, function, args, nargs); +} + +void switch_task() +{ + /* Switch the current task. */ + + current_task++; + if (current_task == max_tasks) current_task = 0; + + /* Indicate the current stack pointer and task registers. */ + + current_stack_pointer = &stack_pointers[current_task]; + current_registers = registers[current_task]; +} diff -r 134efe2c5a9f -r e572b72b9a83 stage2/tasks.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/tasks.h Sat Apr 23 18:19:38 2016 +0200 @@ -0,0 +1,12 @@ +#ifndef __TASKS_H__ +#define __TASKS_H__ + +#include "xburst_types.h" + +/* Task management functions. */ + +void init_tasks(void); +void start_task(unsigned short, void (*)(), u32[], u8); +void switch_task(void); + +#endif /* __TASKS_H__ */