takes one uart input interrupt, then panics
This commit is contained in:
parent
50cbc75102
commit
a9c1a6f742
|
@ -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
16
proc.c
|
@ -365,6 +365,22 @@ scheduler(void)
|
|||
// Enable interrupts on this processor.
|
||||
// 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);
|
||||
|
|
56
riscv.h
56
riscv.h
|
@ -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
13
trap.c
|
@ -42,6 +42,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
19
uart.c
|
@ -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
5
vm.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue