From ffb2c4adfb8e65e355b39abd39d994eebc649c98 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 3 Jan 2020 04:53:01 +0100 Subject: add (not yet fully working - it can only send through uart now) interrupt-driven uart together with "scheduler" --- PL0_test.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'PL0_test.c') diff --git a/PL0_test.c b/PL0_test.c index c6cbe18..fed62a2 100644 --- a/PL0_test.c +++ b/PL0_test.c @@ -7,7 +7,9 @@ void PL0_main(void) // implemented correctly, this shall get printed 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(); -- cgit v1.2.3 From 06991bb6572c1eb814ee35256b3c2bd06519acd2 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 3 Jan 2020 16:41:41 +0100 Subject: fix interrupt enabling/disabling/polling and uart fifo setting to make the io work properly --- PL0_test.c | 2 -- armclock.h | 12 +++++++++++- interrupts.c | 11 +---------- scheduler.c | 4 +--- uart.c | 11 +++++++++-- uart.h | 4 ++-- 6 files changed, 24 insertions(+), 20 deletions(-) (limited to 'PL0_test.c') diff --git a/PL0_test.c b/PL0_test.c index fed62a2..0bfebc7 100644 --- a/PL0_test.c +++ b/PL0_test.c @@ -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(); diff --git a/armclock.h b/armclock.h index 2b2aec9..f81f363 100644 --- a/armclock.h +++ b/armclock.h @@ -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); diff --git a/uart.c b/uart.c index c9fcd35..c4ae445 100644 --- a/uart.c +++ b/uart.c @@ -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) diff --git a/uart.h b/uart.h index ce27d4e..eba292a 100644 --- a/uart.h +++ b/uart.h @@ -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) -- cgit v1.2.3