takes one uart input interrupt, then panics

This commit is contained in:
Robert Morris 2019-06-03 14:13:07 -04:00
parent 50cbc75102
commit a9c1a6f742
6 changed files with 108 additions and 6 deletions

View file

@ -13,9 +13,12 @@
// end -- start of kernel page allocation area
// PHYSTOP -- end RAM used by the kernel
// registers start here in physical memory.
// qemu puts UART registers here in physical memory.
#define UART0 0x10000000L
// qemu puts programmable interrupt controller here.
#define PLIC 0x0c000000L
#define RAMDISK 0x88000000
// the kernel expects there to be RAM

16
proc.c
View file

@ -366,6 +366,22 @@ scheduler(void)
// XXX riscv
//sti();
if(0){ uint x = * (uint*) 0xc001000;
if(x != 0){
printf("pending %x\n", x);
}
x = *(uint*)0xc001004;
if(x != 0)
printf("pending %x\n", x);
}
if(0){
uint uartgetc(void);
uint x = uartgetc();
if(x != 0)
printf("%x ", x);
}
// Loop over process table looking for process to run.
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){

56
riscv.h
View file

@ -30,7 +30,11 @@ w_mepc(uint64 x)
// Supervisor Status Register, sstatus
#define SSTATUS_SPP (1L << 8) // 1=Supervisor, 0=User
#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
#define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
#define SSTATUS_UIE (1L << 0) // User Interrupt Enable
static inline uint64
r_sstatus()
@ -46,6 +50,33 @@ w_sstatus(uint64 x)
asm("csrw sstatus, %0" : : "r" (x));
}
// Supervisor Interrupt Pending
static inline uint64
r_sip()
{
uint64 x;
asm("csrr %0, sip" : "=r" (x) );
return x;
}
// Supervisor Interrupt Enable
#define SIE_SEIE (1L << 9) // external
#define SIE_STIE (1L << 5) // timer
#define SIE_SSIE (1L << 1) // software
static inline uint64
r_sie()
{
uint64 x;
asm("csrr %0, sie" : "=r" (x) );
return x;
}
static inline void
w_sie(uint64 x)
{
asm("csrw sie, %0" : : "r" (x));
}
// machine exception program counter, holds the
// instruction address to which a return from
// exception will go.
@ -147,6 +178,29 @@ r_stval()
return x;
}
// enable interrupts
static inline void
intr_on()
{
w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);
w_sstatus(r_sstatus() | SSTATUS_SIE);
}
// disable interrupts
static inline void
intr_off()
{
w_sstatus(r_sstatus() & ~SSTATUS_SIE);
}
// are interrupts enabled?
static inline int
intr_get()
{
uint64 x = r_sstatus();
return (x & SSTATUS_SIE) != 0;
}
#define PGSIZE 4096 // bytes per page
#define PGSHIFT 12 // bits of offset within a page

13
trap.c
View file

@ -43,6 +43,19 @@ usertrap(void)
// save user program counter.
p->tf->epc = r_sepc();
// PLIC setup
// qemu makes UART0 be interrupt number 10.
int irq = 10;
// set uart's priority to be non-zero (otherwise disabled).
*(uint*)(0x0c000000L + irq*4) = 1;
// set uart's enable bit for hart 0 s-mode.
*(uint*)0x0c002080 = (1 << irq);
// hart 0 S-mode priority threshold.
*(uint*)0x0c201000 = 0;
intr_on();
if(r_scause() == 8){
// system call

19
uart.c
View file

@ -1,4 +1,10 @@
#include "types.h"
#include "param.h"
#include "memlayout.h"
#include "riscv.h"
#include "proc.h"
#include "spinlock.h"
#include "defs.h"
//
// qemu -machine virt has a 16550a UART
@ -9,12 +15,12 @@
//
// address of one of the registers
#define R(reg) ((unsigned int*)(UART0 + 4*(reg)))
#define R(reg) ((volatile unsigned char *)(UART0 + reg))
void
uartinit(void)
{
// disable interrupts
// disable interrupts -- IER
*R(1) = 0x00;
// special mode to set baud rate
@ -30,8 +36,11 @@ uartinit(void)
// and set word length to 8 bits, no parity.
*R(3) = 0x03;
// reset and enable FIFOs.
// reset and enable FIFOs -- FCR.
*R(2) = 0x07;
// enable receive interrupts -- IER.
*R(1) = 0x01;
}
void
@ -40,9 +49,11 @@ uartputc(int c)
*R(0) = c;
}
static int
uint
uartgetc(void)
{
// XXX this isn't right, must check there's data in the FIFO.
return *R(0);
}
void

5
vm.c
View file

@ -30,6 +30,11 @@ kvminit()
mappages(kernel_pagetable, UART0, PGSIZE,
UART0, PTE_R | PTE_W);
// PLIC
mappages(kernel_pagetable, PLIC, 0x4000000,
PLIC, PTE_R | PTE_W);
// map kernel text executable and read-only.
mappages(kernel_pagetable, KERNBASE, (uint64)etext-KERNBASE,
KERNBASE, PTE_R | PTE_X);