diff options
author | Wojtek Kosior <kwojtus@protonmail.com> | 2020-01-03 16:41:41 +0100 |
---|---|---|
committer | Wojtek Kosior <kwojtus@protonmail.com> | 2020-01-03 16:41:41 +0100 |
commit | 06991bb6572c1eb814ee35256b3c2bd06519acd2 (patch) | |
tree | 7d9d128a60d44ee5d0a3c74d84ac05132d326cea | |
parent | ffb2c4adfb8e65e355b39abd39d994eebc649c98 (diff) | |
download | rpi-MMU-example-06991bb6572c1eb814ee35256b3c2bd06519acd2.tar.gz rpi-MMU-example-06991bb6572c1eb814ee35256b3c2bd06519acd2.zip |
fix interrupt enabling/disabling/polling and uart fifo setting to make the io work properly
-rw-r--r-- | PL0_test.c | 2 | ||||
-rw-r--r-- | armclock.h | 12 | ||||
-rw-r--r-- | interrupts.c | 11 | ||||
-rw-r--r-- | scheduler.c | 4 | ||||
-rw-r--r-- | uart.c | 11 | ||||
-rw-r--r-- | uart.h | 4 |
6 files changed, 24 insertions, 20 deletions
@@ -8,8 +8,6 @@ void PL0_main(void) puts("Hello userspace! Type 'f' if you want me to try accessing " "kernel memory!"); - - asm volatile("mov r0, #17\n\rsvc #0" ::: "r0"); while (1) { char c = getchar(); @@ -46,11 +46,21 @@ static inline void armclk_init(void) static inline void armclk_enable_timer_irq(void) { + armclk_control_t ctrl = + (armclk_control_t) *(uint32_t volatile*) ARMCLK_CONTROL; + ctrl.fields.interrupt_enable = 1; + *(uint32_t volatile*) ARMCLK_CONTROL = ctrl.raw; + *(uint32_t volatile*) ARM_ENABLE_BASIC_IRQS = 1; } static inline void armclk_disable_timer_irq(void) { + armclk_control_t ctrl = + (armclk_control_t) *(uint32_t volatile*) ARMCLK_CONTROL; + ctrl.fields.interrupt_enable = 0; + *(uint32_t volatile*) ARMCLK_CONTROL = ctrl.raw; + *(uint32_t volatile*) ARM_DISABLE_BASIC_IRQS = 1; } @@ -62,7 +72,7 @@ static inline void armclk_irq_settimeout(uint32_t timeout) static inline _Bool armclk_irq_pending(void) { - return *(uint32_t volatile*) ARMCLK_RAW_IRQ; + return *(uint32_t volatile*) ARM_IRQ_BASIC_PENDING & 1; } #endif // ARMCLOCK_H diff --git a/interrupts.c b/interrupts.c index 9beee0a..bf7ed02 100644 --- a/interrupts.c +++ b/interrupts.c @@ -18,7 +18,7 @@ void undefined_instruction_vector(void) { error("Undefined instruction occured"); } -_Bool flag = 0; + uint32_t supervisor_call_handler(uint32_t regs[14]) { switch(regs[0]) { @@ -38,15 +38,6 @@ uint32_t supervisor_call_handler(uint32_t regs[14]) case UART_WRITE: error("UART_WRITE not implemented!!!!!"); break; - case 17: - { - flag = 1; - /* while (1) */ - /* { */ - /* printbin(*(uint32_t volatile*) PL011_UART_MIS); puts(""); */ - /* } */ - break; - } default: // perhaps we should kill the process now? error("unknown supervisor call type!!!!!"); diff --git a/scheduler.c b/scheduler.c index 3399bf4..141ba1d 100644 --- a/scheduler.c +++ b/scheduler.c @@ -113,7 +113,6 @@ schedule_save_context(uint32_t regs[14]) schedule(); } -extern _Bool flag; void __attribute__((noreturn)) schedule(void) { @@ -126,7 +125,6 @@ void __attribute__((noreturn)) schedule(void) new_CPSR.fields.PSR_IRQ_MASK_BIT = 0; write_CPSR(new_CPSR); - if (flag) putchar('l'); asm volatile("wfi"); @@ -146,8 +144,8 @@ void __attribute__((noreturn)) schedule(void) [stackaddr]"r" (PL0_sp), [linkaddr]"r" (PL0_lr) : "memory"); - armclk_enable_timer_irq(); armclk_irq_settimeout(0x00100000); + armclk_enable_timer_irq(); write_SPSR(PL0_PSR); @@ -52,11 +52,14 @@ void uart_init() // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40. mmio_write(PL011_UART_FBRD, 40); - // Enable FIFO & 8 bit data transmission (1 stop bit, no parity). - mmio_write(PL011_UART_LCRH, (1 << 4) | (1 << 5) | (1 << 6)); + // Set 8 bit data transmission (1 stop bit, no parity) + // and disable FIFO to be able to receive interrupt every received + // char, not every 2 chars + mmio_write(PL011_UART_LCRH, (1 << 5) | (1 << 6)); // set interrupt to come when transmit FIFO becomes ≤ 1/8 full // or receive FIFO becomes ≥ 1/8 full + // (not really matters, since we disabled FIFOs) mmio_write(PL011_UART_IFLS, 0); // Enable PL011_UART, receive & transfer part of UART.2 @@ -64,6 +67,10 @@ void uart_init() // At first, it's probably safer to disable interrupts :) uart_irq_disable(); + + // That disables the entire uart irq; also disable single sources + // within it + *(uint32_t volatile*) PL011_UART_IMSC = 0; } inline static _Bool can_transmit(void) @@ -61,7 +61,7 @@ static inline void uart_irq_enable(void) static inline _Bool uart_recv_irq_pending(void) { - return ((uint32_t) 1 << 4) & *(uint32_t volatile*) PL011_UART_RIS; + return ((uint32_t) 1 << 4) & *(uint32_t volatile*) PL011_UART_MIS; } static inline void uart_recv_irq_disable(void) @@ -81,7 +81,7 @@ static inline void uart_clear_recv_irq(void) static inline _Bool uart_send_irq_pending(void) { - return ((uint32_t) 1 << 5) & *(uint32_t volatile*) PL011_UART_RIS; + return ((uint32_t) 1 << 5) & *(uint32_t volatile*) PL011_UART_MIS; } static inline void uart_send_irq_disable(void) |