1.1 --- a/stage2/Makefile Sat Apr 23 17:26:50 2016 +0200
1.2 +++ b/stage2/Makefile Sat Apr 23 18:19:38 2016 +0200
1.3 @@ -62,8 +62,8 @@
1.4
1.5 # Ordering of objects is important and cannot be left to replacement rules.
1.6
1.7 -SRC = head2.S entry.S handlers.S stage2.c cpu.c lcd.c jzlcd.c board.c irq.c $(BOARD_SRC)
1.8 -OBJ = head2.o entry.o handlers.o stage2.o cpu.o lcd.o jzlcd.o board.o irq.o $(BOARD_OBJ)
1.9 +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)
1.10 +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)
1.11
1.12 .PHONY: all clean distclean
1.13
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/stage2/example.c Sat Apr 23 18:19:38 2016 +0200
2.3 @@ -0,0 +1,57 @@
2.4 +/*
2.5 + * Example tasks.
2.6 + *
2.7 + * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
2.8 + *
2.9 + * This program is free software: you can redistribute it and/or modify
2.10 + * it under the terms of the GNU General Public License as published by
2.11 + * the Free Software Foundation, either version 3 of the License, or
2.12 + * (at your option) any later version.
2.13 + *
2.14 + * This program is distributed in the hope that it will be useful,
2.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 + * GNU General Public License for more details.
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License
2.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
2.21 + */
2.22 +
2.23 +#include "board.h"
2.24 +#include "lcd.h"
2.25 +#include "jzlcd.h"
2.26 +#include "tasks.h"
2.27 +
2.28 +extern vidinfo_t panel_info;
2.29 +
2.30 +void next_pixel(unsigned short *x, unsigned short *y)
2.31 +{
2.32 + (*x)++;
2.33 + if (*x >= panel_info.vl_col) {
2.34 + *x = 0;
2.35 + (*y)++;
2.36 + if (*y >= panel_info.vl_row)
2.37 + *y = 0;
2.38 + }
2.39 +}
2.40 +
2.41 +/* Tasks. */
2.42 +
2.43 +void plot_pattern(unsigned short pixel_type, unsigned short x, unsigned short y)
2.44 +{
2.45 + while (1) {
2.46 + if (pixel_type)
2.47 + test_pixel(x, y, pixel_type);
2.48 + else
2.49 + clear_pixel(x, y);
2.50 + next_pixel(&x, &y);
2.51 + udelay(100);
2.52 + }
2.53 +}
2.54 +
2.55 +void start_plot_pattern(unsigned short task)
2.56 +{
2.57 + u32 args[] = {task, 0, (task - 1) * 60};
2.58 +
2.59 + start_task(task, (void (*)()) plot_pattern, args, 3);
2.60 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/stage2/example.h Sat Apr 23 18:19:38 2016 +0200
3.3 @@ -0,0 +1,9 @@
3.4 +#ifndef __EXAMPLE_H__
3.5 +#define __EXAMPLE_H__
3.6 +
3.7 +/* Example task functions. */
3.8 +
3.9 +void plot_pattern(unsigned short, unsigned short, unsigned short);
3.10 +void start_plot_pattern(unsigned short);
3.11 +
3.12 +#endif /* __EXAMPLE_H__ */
4.1 --- a/stage2/irq.c Sat Apr 23 17:26:50 2016 +0200
4.2 +++ b/stage2/irq.c Sat Apr 23 18:19:38 2016 +0200
4.3 @@ -21,54 +21,9 @@
4.4
4.5 #include "init.h"
4.6 #include "board.h"
4.7 -#include "lcd.h"
4.8 -#include "jzlcd.h"
4.9 #include "cpu.h"
4.10 -#include "paging.h"
4.11 #include "irq.h"
4.12 -
4.13 -extern vidinfo_t panel_info;
4.14 -
4.15 -void next_pixel(unsigned short *x, unsigned short *y)
4.16 -{
4.17 - (*x)++;
4.18 - if (*x >= panel_info.vl_col) {
4.19 - *x = 0;
4.20 - (*y)++;
4.21 - if (*y >= panel_info.vl_row)
4.22 - *y = 0;
4.23 - }
4.24 -}
4.25 -
4.26 -/* Task management. */
4.27 -
4.28 -enum { max_tasks = 3 };
4.29 -static u32 stack_pointers[max_tasks];
4.30 -static u32 registers[max_tasks][32];
4.31 -
4.32 -u8 current_task;
4.33 -u32 *current_stack_pointer;
4.34 -u32 *current_registers;
4.35 -
4.36 -extern u32 _got_copy_start;
4.37 -
4.38 -const u32 stack_start = 0x00080000;
4.39 -const u32 stack_size = 0x00002000;
4.40 -const u32 pagesize = 4 * 1024;
4.41 -
4.42 -/* Tasks. */
4.43 -
4.44 -void plot_pattern(unsigned short pixel_type, unsigned short x, unsigned short y)
4.45 -{
4.46 - while (1) {
4.47 - if (pixel_type)
4.48 - test_pixel(x, y, pixel_type);
4.49 - else
4.50 - clear_pixel(x, y);
4.51 - next_pixel(&x, &y);
4.52 - udelay(100);
4.53 - }
4.54 -}
4.55 +#include "tasks.h"
4.56
4.57 /* Initialisation and handling. */
4.58
4.59 @@ -104,48 +59,3 @@
4.60 }
4.61 }
4.62 }
4.63 -
4.64 -void init_tasks()
4.65 -{
4.66 - current_task = 0;
4.67 - current_stack_pointer = &stack_pointers[current_task];
4.68 - current_registers = registers[current_task];
4.69 -}
4.70 -
4.71 -void start_task(unsigned short task)
4.72 -{
4.73 - u32 args[] = {task, 0, (task - 1) * 60};
4.74 - u32 virtual, physical;
4.75 -
4.76 - /*
4.77 - Each task employs a stack at a multiple of the given start address in
4.78 - physical memory, but at the same address in virtual memory.
4.79 - */
4.80 -
4.81 - virtual = stack_start;
4.82 - physical = stack_start - stack_size * task;
4.83 -
4.84 - init_page_table(page_table_start, virtual - pagesize * 2, physical - pagesize * 2, pagesize, 0x1e, task);
4.85 -
4.86 - stack_pointers[task] = virtual - 12;
4.87 -
4.88 - /*
4.89 - Set the registers for the new task, initialising the global pointer and
4.90 - return address.
4.91 - */
4.92 -
4.93 - init_registers(registers[task], _got_copy_start, (void (*)()) plot_pattern, args, 3);
4.94 -}
4.95 -
4.96 -void switch_task()
4.97 -{
4.98 - /* Switch the current task. */
4.99 -
4.100 - current_task++;
4.101 - if (current_task == max_tasks) current_task = 0;
4.102 -
4.103 - /* Indicate the current stack pointer and task registers. */
4.104 -
4.105 - current_stack_pointer = &stack_pointers[current_task];
4.106 - current_registers = registers[current_task];
4.107 -}
5.1 --- a/stage2/irq.h Sat Apr 23 17:26:50 2016 +0200
5.2 +++ b/stage2/irq.h Sat Apr 23 18:19:38 2016 +0200
5.3 @@ -4,9 +4,5 @@
5.4 /* Initialisation functions. */
5.5
5.6 void irq_init(void);
5.7 -void init_tasks(void);
5.8 -void start_task(unsigned short);
5.9 -void switch_task(void);
5.10 -void plot_pattern(unsigned short, unsigned short, unsigned short);
5.11
5.12 #endif /* __IRQ_H__ */
6.1 --- a/stage2/stage2.c Sat Apr 23 17:26:50 2016 +0200
6.2 +++ b/stage2/stage2.c Sat Apr 23 18:19:38 2016 +0200
6.3 @@ -22,6 +22,8 @@
6.4 #include "irq.h"
6.5 #include "lcd.h"
6.6 #include "cpu.h"
6.7 +#include "tasks.h"
6.8 +#include "example.h"
6.9
6.10 void c_main(void)
6.11 {
6.12 @@ -48,8 +50,8 @@
6.13 /* Start the tasks. */
6.14
6.15 init_tasks();
6.16 - start_task(1);
6.17 - start_task(2);
6.18 + start_plot_pattern(1);
6.19 + start_plot_pattern(2);
6.20
6.21 /* Now, wait for the tasks to be selected as interrupts occur. */
6.22
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/stage2/tasks.c Sat Apr 23 18:19:38 2016 +0200
7.3 @@ -0,0 +1,92 @@
7.4 +/*
7.5 + * Task handling.
7.6 + *
7.7 + * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
7.8 + *
7.9 + * This program is free software: you can redistribute it and/or modify
7.10 + * it under the terms of the GNU General Public License as published by
7.11 + * the Free Software Foundation, either version 3 of the License, or
7.12 + * (at your option) any later version.
7.13 + *
7.14 + * This program is distributed in the hope that it will be useful,
7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.17 + * GNU General Public License for more details.
7.18 + *
7.19 + * You should have received a copy of the GNU General Public License
7.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7.21 + */
7.22 +
7.23 +#include "cpu.h"
7.24 +#include "paging.h"
7.25 +
7.26 +/* Task tables and data. */
7.27 +
7.28 +enum { max_tasks = 3 };
7.29 +static u32 stack_pointers[max_tasks];
7.30 +static u32 registers[max_tasks][32];
7.31 +
7.32 +u8 current_task;
7.33 +u32 *current_stack_pointer;
7.34 +u32 *current_registers;
7.35 +
7.36 +/* Address locations and paging configuration. */
7.37 +
7.38 +const u32 stack_start = 0x00080000;
7.39 +const u32 stack_size = 0x00002000;
7.40 +const u32 pagesize = 4 * 1024;
7.41 +
7.42 +/* The unrelocated symbol table location. */
7.43 +
7.44 +extern u32 _got_copy_start;
7.45 +
7.46 +/* Task management functions. */
7.47 +
7.48 +void init_tasks()
7.49 +{
7.50 + current_task = 0;
7.51 + current_stack_pointer = &stack_pointers[current_task];
7.52 + current_registers = registers[current_task];
7.53 +}
7.54 +
7.55 +void start_task(unsigned short task, void (*function)(), u32 args[], unsigned short nargs)
7.56 +{
7.57 + u32 virtual, physical;
7.58 +
7.59 + /*
7.60 + Each task employs a stack at a multiple of the given start address in
7.61 + physical memory, but at the same address in virtual memory.
7.62 + */
7.63 +
7.64 + virtual = stack_start;
7.65 + physical = stack_start - stack_size * task;
7.66 +
7.67 + init_page_table(page_table_start, virtual - pagesize * 2, physical - pagesize * 2, pagesize, 0x1e, task);
7.68 +
7.69 + /*
7.70 + Subtract from the stack pointer to prevent the called function from
7.71 + reaching into unmapped memory.
7.72 + */
7.73 +
7.74 + stack_pointers[task] = virtual - 12;
7.75 +
7.76 + /*
7.77 + Set the registers for the new task, initialising the global pointer and
7.78 + return address.
7.79 + */
7.80 +
7.81 + init_registers(registers[task], _got_copy_start, function, args, nargs);
7.82 +}
7.83 +
7.84 +void switch_task()
7.85 +{
7.86 + /* Switch the current task. */
7.87 +
7.88 + current_task++;
7.89 + if (current_task == max_tasks) current_task = 0;
7.90 +
7.91 + /* Indicate the current stack pointer and task registers. */
7.92 +
7.93 + current_stack_pointer = &stack_pointers[current_task];
7.94 + current_registers = registers[current_task];
7.95 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/stage2/tasks.h Sat Apr 23 18:19:38 2016 +0200
8.3 @@ -0,0 +1,12 @@
8.4 +#ifndef __TASKS_H__
8.5 +#define __TASKS_H__
8.6 +
8.7 +#include "xburst_types.h"
8.8 +
8.9 +/* Task management functions. */
8.10 +
8.11 +void init_tasks(void);
8.12 +void start_task(unsigned short, void (*)(), u32[], u8);
8.13 +void switch_task(void);
8.14 +
8.15 +#endif /* __TASKS_H__ */