aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <kwojtus@protonmail.com>2020-01-03 16:41:41 +0100
committerWojtek Kosior <kwojtus@protonmail.com>2020-01-03 16:41:41 +0100
commit06991bb6572c1eb814ee35256b3c2bd06519acd2 (patch)
tree7d9d128a60d44ee5d0a3c74d84ac05132d326cea
parentffb2c4adfb8e65e355b39abd39d994eebc649c98 (diff)
downloadrpi-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.c2
-rw-r--r--armclock.h12
-rw-r--r--interrupts.c11
-rw-r--r--scheduler.c4
-rw-r--r--uart.c11
-rw-r--r--uart.h4
6 files changed, 24 insertions, 20 deletions
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)