Compare commits

..

No commits in common. "71c3b30bd01655370001a3f19e603101d597245e" and "753489b857b31100ddc173f9a50242601b71c66c" have entirely different histories.

9 changed files with 4 additions and 26 deletions

View file

@ -35,7 +35,6 @@ The timers are set up using these calls:
```c
irq_init_vectors();
enable_interrupt_controller();
irq_barrier();
irq_enable();
timer_init();
```
@ -78,7 +77,7 @@ In the middle we simply call a function called `handle_irq()` which is written i
void handle_irq() {
unsigned int irq = REGS_IRQ->irq0_pending_0;
while(irq & (SYS_TIMER_IRQ_1 | SYS_TIMER_IRQ_3)) {
while(irq) {
if (irq & SYS_TIMER_IRQ_1) {
irq &= ~SYS_TIMER_IRQ_1;
@ -118,9 +117,7 @@ To begin receiving interrupts, we need to take one more step: unmasking all type
Masking is a technique used by the CPU to prevent a particular piece of code from being stopped in its tracks by an interrupt. It's used to protect important code that *must* complete. Imagine what would happen if our `kernel_entry` code (that saves register state) was interrupted halfway through! In this case, the register state would be overwritten and lost. This is why the CPU automatically masks all interrupts when an exception handler is executed.
The `irq_enable` and `irq_disable` functions in _utils.S_ are responsible for masking and unmasking interrupts.
They are helped by the `irq_barrier` function which ensures that the `enable_interrupt_controller()` call properly finishes before the `irq_enable()` call is made:
The `irq_enable` and `irq_disable` functions in _utils.S_ are responsible for masking and unmasking interrupts:
```c
.globl irq_enable
@ -132,11 +129,6 @@ irq_enable:
irq_disable:
msr daifset, #2
ret
.globl irq_barrier
irq_barrier:
dsb sy
ret
```
As soon as `irq_enable()` is called from `main()` in _kernel.c_, the timer handler is run when the timer interrupt fires. Well, sort of...!

View file

@ -11,7 +11,7 @@ void disable_interrupt_controller() {
void handle_irq() {
unsigned int irq = REGS_IRQ->irq0_pending_0;
while(irq & (SYS_TIMER_IRQ_1 | SYS_TIMER_IRQ_3)) {
while(irq) {
if (irq & SYS_TIMER_IRQ_1) {
irq &= ~SYS_TIMER_IRQ_1;

View file

@ -120,7 +120,6 @@ void main(void)
irq_init_vectors();
enable_interrupt_controller();
irq_barrier();
irq_enable();
timer_init();

View file

@ -38,7 +38,6 @@ enum vc_irqs {
void irq_init_vectors();
void irq_enable();
void irq_barrier();
void irq_disable();
void enable_interrupt_controller();
void disable_interrupt_controller();

View file

@ -13,8 +13,3 @@ irq_enable:
irq_disable:
msr daifset, #2
ret
.globl irq_barrier
irq_barrier:
dsb sy
ret

View file

@ -11,7 +11,7 @@ void disable_interrupt_controller() {
void handle_irq() {
unsigned int irq = REGS_IRQ->irq0_pending_0;
while(irq & (SYS_TIMER_IRQ_1 | SYS_TIMER_IRQ_3)) {
while(irq) {
if (irq & SYS_TIMER_IRQ_1) {
irq &= ~SYS_TIMER_IRQ_1;

View file

@ -147,7 +147,6 @@ void main(void)
irq_init_vectors();
enable_interrupt_controller();
irq_barrier();
irq_enable();
timer_init();

View file

@ -38,7 +38,6 @@ enum vc_irqs {
void irq_init_vectors();
void irq_enable();
void irq_barrier();
void irq_disable();
void enable_interrupt_controller();
void disable_interrupt_controller();

View file

@ -13,8 +13,3 @@ irq_enable:
irq_disable:
msr daifset, #2
ret
.globl irq_barrier
irq_barrier:
dsb sy
ret