Skip to content

Commit

Permalink
user: create first demo that display ascii art
Browse files Browse the repository at this point in the history
  • Loading branch information
roemvaar committed Apr 8, 2024
1 parent 3b6c7e3 commit 0cfd3b4
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 128 deletions.
74 changes: 16 additions & 58 deletions include/peripherals/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,31 @@

#include "base.h"

// struct arm_irq_regs_2711 {
// volatile unsigned int irq0_pending0;
// volatile unsigned int irq0_pending1;
// volatile unsigned int irq0_pending2;
// volatile unsigned int irq0_set_en_0;
// volatile unsigned int irq0_set_en_1;
// volatile unsigned int irq0_set_en_2;
// volatile unsigned int irq_clr_en_0;
// volatile unsigned int irq_clr_en_1;
// volatile unsigned int irq_clr_en_2;
// volatile unsigned int irq_status0;
// volatile unsigned int irq_status1;
// volatile unsigned int irq_status2;
// };

// typedef struct arm_irq_regs_2711 arm_irq_regs;

// #define GIC_BASE 0xFF840000
// #define GICD_DIST_BASE (GIC_BASE + 0x00001000)
// #define GICC_CPU_BASE (GIC_BASE + 0x00002000)

// #define GICD_ENABLE_IRQ_BASE (GICD_DIST_BASE + 0x00000100)

// #define GICC_IAR (GICC_CPU_BASE + 0x0000000C)
// #define GICC_EOIR (GICC_CPU_BASE + 0x00000010)

// #define GIC_IRQ_TARGET_BASE (GICD_DIST_BASE+0x00000800)

// //VC (=VideoCore) starts at 96
// #define SYSTEM_TIMER_IRQ_0 (0x60) //96
// #define SYSTEM_TIMER_IRQ_1 (0x61) //97
// #define SYSTEM_TIMER_IRQ_2 (0x62) //98
// #define SYSTEM_TIMER_IRQ_3 (0x63) //99

// // #define REGS_IRQ ((arm_irq_regs *)(GIC_BASE + 0x0000B200))
// #define REGS_IRQ ((arm_irq_regs *)(0xFF00B200))

// enum vc_irqs {
// SYS_TIMER_IRQ_0 = 1,
// SYS_TIMER_IRQ_1 = 2,
// SYS_TIMER_IRQ_2 = 4,
// SYS_TIMER_IRQ_3 = 8,
// AUX_IRQ = (1 << 29)
// };

#define GIC_BASE 0xFF840000
#define GICD_DIST_BASE (GIC_BASE+0x00001000)
#define GICC_CPU_BASE (GIC_BASE+0x00002000)
#define GICD_DIST_BASE (GIC_BASE + 0x00001000)
#define GICC_CPU_BASE (GIC_BASE + 0x00002000)

#define GICD_ENABLE_IRQ_BASE (GICD_DIST_BASE+0x00000100)
#define GICD_ENABLE_IRQ_BASE (GICD_DIST_BASE + 0x00000100)

#define GICC_IAR (GICC_CPU_BASE+0x0000000C)
#define GICC_EOIR (GICC_CPU_BASE+0x00000010)
#define GICC_IAR (GICC_CPU_BASE + 0x0000000C)
#define GICC_EOIR (GICC_CPU_BASE + 0x00000010)

#define GIC_IRQ_TARGET_BASE (GICD_DIST_BASE+0x00000800)
#define GIC_IRQ_TARGET_BASE (GICD_DIST_BASE + 0x00000800)

//VC (=VideoCore) starts at 96
#define SYSTEM_TIMER_IRQ_0 (0x60) //96
#define SYSTEM_TIMER_IRQ_1 (0x61) //97
#define SYSTEM_TIMER_IRQ_2 (0x62) //98
#define SYSTEM_TIMER_IRQ_3 (0x63) //99
/* VideoCore interrupts
*
* VC (=VideoCore) starts at 96
* BCM2711 ARM Peripherals, p.87/166
*/
#define SYSTEM_TIMER_IRQ_0 (0x60) // 96
#define SYSTEM_TIMER_IRQ_1 (0x61) // 97
#define SYSTEM_TIMER_IRQ_2 (0x62) // 98
#define SYSTEM_TIMER_IRQ_3 (0x63) // 99

void enable_interrupt_controller(void);
void disable_interrupt_controller(void);
void handle_irq(void);

// In assembly file
/* In irq.S assembly file */
extern void exception_vectors_init(void);
extern void irq_enable(void);
extern void irq_disable(void);
Expand Down
15 changes: 8 additions & 7 deletions include/peripherals/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

// static char* const SYS_TIMER_BASE = (char*)(PERIPHERALS_BASE + 0x3000);

#define TIMER_CS (PERIPHERALS_BASE+0x00003000)
#define TIMER_CLO (PERIPHERALS_BASE+0x00003004)
#define TIMER_CHI (PERIPHERALS_BASE+0x00003008)
#define TIMER_C0 (PERIPHERALS_BASE+0x0000300C)
#define TIMER_C1 (PERIPHERALS_BASE+0x00003010)
#define TIMER_C2 (PERIPHERALS_BASE+0x00003014)
#define TIMER_C3 (PERIPHERALS_BASE+0x00003018)
#define TIMER_CS (PERIPHERALS_BASE + 0x00003000)
#define TIMER_CLO (PERIPHERALS_BASE + 0x00003004)
#define TIMER_CHI (PERIPHERALS_BASE + 0x00003008)
#define TIMER_C0 (PERIPHERALS_BASE + 0x0000300C)
#define TIMER_C1 (PERIPHERALS_BASE + 0x00003010)
#define TIMER_C2 (PERIPHERALS_BASE + 0x00003014)
#define TIMER_C3 (PERIPHERALS_BASE + 0x00003018)

#define TIMER_CS_M0 (1 << 0)
#define TIMER_CS_M1 (1 << 1)
Expand All @@ -47,5 +47,6 @@ struct timer_regs
uint32_t sys_timer_get_count(void);
void sys_timer_init(void);
void handle_timer_1_irq(void);
void handle_timer_3_irq(void);

#endif /* PERIPHERALS_TIMER_H_ */
87 changes: 45 additions & 42 deletions include/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,56 +48,59 @@ typedef enum
/* CPUContext_t
*
*/
// typedef struct _cpu_context
// {
// unsigned long x0;
// unsigned long x1;
// unsigned long x2;
// unsigned long x3;
// unsigned long x4;
// unsigned long x5;
// unsigned long x6;
// unsigned long x7;
// unsigned long x8;
// unsigned long x9;
// unsigned long x10;
// unsigned long x11;
// unsigned long x12;
// unsigned long x13;
// unsigned long x14;
// unsigned long x15;
// unsigned long x16;
// unsigned long x17;
// unsigned long x18;
// unsigned long x19;
// unsigned long x20;
// unsigned long x21;
// unsigned long x22;
// unsigned long x23;
// unsigned long x24;
// unsigned long x25;
// unsigned long x26;
// unsigned long x27;
// unsigned long x28;
// unsigned long x29;
// unsigned long x30;
// unsigned long elr_el1;
// unsigned long spsr_el1;
// unsigned long sp_el0;
// } CPUContext_t;
typedef struct _cpu_context
{
// unsigned long x0;
// unsigned long x1;
// unsigned long x2;
// unsigned long x3;
// unsigned long x4;
// unsigned long x5;
// unsigned long x6;
// unsigned long x7;
// unsigned long x8;
// unsigned long x9;
// unsigned long x10;
// unsigned long x11;
// unsigned long x12;
// unsigned long x13;
// unsigned long x14;
// unsigned long x15;
// unsigned long x16;
// unsigned long x17;
// unsigned long x18;
unsigned long x19;
unsigned long x20;
unsigned long x21;
unsigned long x22;
unsigned long x23;
unsigned long x24;
unsigned long x25;
unsigned long x26;
unsigned long x27;
unsigned long x28;
// unsigned long x29;
// unsigned long x30;
// unsigned long elr_el1;
// unsigned long spsr_el1;
// unsigned long sp_el0;
unsigned long fp;
unsigned long sp;
unsigned long pc;
} CPUContext_t;

/* TaskDescriptor_t
*/
typedef struct _task_descriptor
{
int tid; /* Task identifier (tid), which is unique among all active tasks */
int priority; /* The task's priority */
TaskDescriptor_t *parent_td; /* A pointer to the TaskDescriptor of the task that created it, its parent */
int tid; /* Task identifier (tid), which is unique among all active tasks */
int priority; /* The task's priority */
TaskDescriptor_t *parent_td; /* A pointer to the TaskDescriptor of the task that created it, its parent */
// TaskDescriptor_t *next_task_ready_queue; /* Pointer to TaskDescriptor of the next ready task (schedule) */
// TaskDescriptor_t *next_task_send_queue; /* Pointer to TaskDescriptor of the next ready task (send queue) */
TaskState_t state; /* The task's current run state */
/* TODO */ /* The task's current stack pointer */
/* TODO - CPU Context CPUContext_t *context; This is the context, includes the tasks's SPSR */
/* TODO */ /* The task's current stack pointer */
CPUContext_t cpu_context; /* This is the context, includes the tasks's SPSR */
entry_point function;
} TaskDescriptor_t;

Expand Down
7 changes: 7 additions & 0 deletions include/user/demo1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef USER_DEMO1_H_
#define USER_DEMO1_H_

void user_task(void);
void display_ascii_art(void);

#endif /* USER_DEMO1_H_ */
22 changes: 15 additions & 7 deletions src/armv8.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#define FIQ_INVALID_EL0_32 14
#define ERROR_INVALID_EL0_32 15

// Stack frame size
#define S_FRAME_SIZE 256 // Size of all saved registers
/* Stack frame size - size of all stored registers */
#define S_FRAME_SIZE 256

/* Kernel entry */
.macro kernel_entry
Expand All @@ -42,8 +42,7 @@
str x30, [sp, #16 * 15]
.endm

// Kernel exit
// .macro kernel_exit, el
/* Kernel exit */
.macro kernel_exit
ldp x0, x1, [sp, #16 * 0]
ldp x2, x3, [sp, #16 * 1]
Expand All @@ -65,7 +64,7 @@
eret
.endm

// .macro handle_invalid_entry el, type
/* Handle invalid entry */
.macro handle_invalid_entry type
kernel_entry
mov x0, #\type
Expand All @@ -75,6 +74,7 @@
b err_hang
.endm

/* `ventry` is used to create entries in the vector table */
.macro ventry label
.balign 0x80
b \label
Expand Down Expand Up @@ -154,7 +154,11 @@ fiq_invalid_el0_32:
error_invalid_el0_32:
handle_invalid_entry ERROR_INVALID_EL0_32

/* IRQ handler */
/* IRQ handler
*
* Note: Whenever an exception handler is executed, the processor
* automatically disables all types of interrupts (masking).
*/
.align 8
handle_el1_irq:
kernel_entry
Expand Down Expand Up @@ -196,7 +200,11 @@ exception_vectors_init:
isb sy
ret

/* Enable IRQ */
/* Enable IRQ
*
* We use the value of 2 because we only want to set (in irq_enable) and
* clear (in irq_disable) second bit that corresponds to the I Mask (IRQs).
*/
.align 8
.global irq_enable
irq_enable:
Expand Down
25 changes: 25 additions & 0 deletions src/demo1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "user/demo1.h"

#include "peripherals/uart.h"

void user_task(void)
{
while (1) {
for (int i = 0; i < 50; i++) {
uart_printf(CONSOLE, "first_task (user): %d\r\n", i);
}
}
}

/* ASCII art
* https://www.asciiart.eu/vehicles/trains
*/
void display_ascii_art(void)
{
uart_printf(CONSOLE, " _____ . . . . . o o o o o\n");
uart_printf(CONSOLE, " __|[_]|__ ___________ _______ ____ o\n");
uart_printf(CONSOLE, " |[] [] []| [] [] [] [] [_____(__ ][]]_n_n__][.\n");
uart_printf(CONSOLE, "_|________|_[_________]_[________]_|__|________)<\n");
uart_printf(CONSOLE, " oo oo 'oo oo ' oo oo 'oo 0000---oo\\_\n");
uart_printf(CONSOLE, " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
11 changes: 8 additions & 3 deletions src/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

void enable_interrupt(unsigned int irq)
{
uart_printf(CONSOLE, "%x\r\n", irq);
uart_printf(CONSOLE, "irq: %x\r\n", irq);
unsigned int n = irq / 32;
unsigned int offset = irq % 32;
unsigned int enableRegister = GICD_ENABLE_IRQ_BASE + (4*n);
uart_printf(CONSOLE, "EnableRegister: %x\r\n", enableRegister);
uart_printf(CONSOLE, "irq: EnableRegister: %x\r\n", enableRegister);
put32(enableRegister, 1 << offset);
}

Expand All @@ -32,12 +32,17 @@ void enable_interrupt_controller()
void handle_irq(void)
{
unsigned int irq_ack_reg = get32(GICC_IAR);
unsigned int irq = irq_ack_reg & 0x2FF;
unsigned int irq = irq_ack_reg & 0x2FF;

switch (irq) {
case (SYSTEM_TIMER_IRQ_1):
put32(GICC_EOIR, irq_ack_reg);
handle_timer_1_irq();
break;
// case (SYSTEM_TIMER_IRQ_3):
// put32(GICC_EOIR, irq_ack_reg);
// handle_timer_3_irq();
// break;
default:
uart_printf(CONSOLE, "irq: Unknown pending irq: %x\r\n", irq);
}
Expand Down
Loading

0 comments on commit 0cfd3b4

Please sign in to comment.