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
|
// end -- start of kernel page allocation area
|
||||||
// PHYSTOP -- end RAM used by the kernel
|
// PHYSTOP -- end RAM used by the kernel
|
||||||
|
|
||||||
// registers start here in physical memory.
|
// qemu puts UART registers here in physical memory.
|
||||||
#define UART0 0x10000000L
|
#define UART0 0x10000000L
|
||||||
|
|
||||||
|
// qemu puts programmable interrupt controller here.
|
||||||
|
#define PLIC 0x0c000000L
|
||||||
|
|
||||||
#define RAMDISK 0x88000000
|
#define RAMDISK 0x88000000
|
||||||
|
|
||||||
// the kernel expects there to be RAM
|
// the kernel expects there to be RAM
|
||||||
|
|
16
proc.c
16
proc.c
|
@ -366,6 +366,22 @@ scheduler(void)
|
||||||
// XXX riscv
|
// XXX riscv
|
||||||
//sti();
|
//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.
|
// Loop over process table looking for process to run.
|
||||||
acquire(&ptable.lock);
|
acquire(&ptable.lock);
|
||||||
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
||||||
|
|
56
riscv.h
56
riscv.h
|
@ -30,7 +30,11 @@ w_mepc(uint64 x)
|
||||||
|
|
||||||
// Supervisor Status Register, sstatus
|
// 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
|
static inline uint64
|
||||||
r_sstatus()
|
r_sstatus()
|
||||||
|
@ -46,6 +50,33 @@ w_sstatus(uint64 x)
|
||||||
asm("csrw sstatus, %0" : : "r" (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
|
// machine exception program counter, holds the
|
||||||
// instruction address to which a return from
|
// instruction address to which a return from
|
||||||
// exception will go.
|
// exception will go.
|
||||||
|
@ -147,6 +178,29 @@ r_stval()
|
||||||
return x;
|
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 PGSIZE 4096 // bytes per page
|
||||||
#define PGSHIFT 12 // bits of offset within a page
|
#define PGSHIFT 12 // bits of offset within a page
|
||||||
|
|
||||||
|
|
13
trap.c
13
trap.c
|
@ -43,6 +43,19 @@ usertrap(void)
|
||||||
// save user program counter.
|
// save user program counter.
|
||||||
p->tf->epc = r_sepc();
|
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){
|
if(r_scause() == 8){
|
||||||
// system call
|
// system call
|
||||||
|
|
||||||
|
|
19
uart.c
19
uart.c
|
@ -1,4 +1,10 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "param.h"
|
||||||
#include "memlayout.h"
|
#include "memlayout.h"
|
||||||
|
#include "riscv.h"
|
||||||
|
#include "proc.h"
|
||||||
|
#include "spinlock.h"
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// qemu -machine virt has a 16550a UART
|
// qemu -machine virt has a 16550a UART
|
||||||
|
@ -9,12 +15,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// address of one of the registers
|
// address of one of the registers
|
||||||
#define R(reg) ((unsigned int*)(UART0 + 4*(reg)))
|
#define R(reg) ((volatile unsigned char *)(UART0 + reg))
|
||||||
|
|
||||||
void
|
void
|
||||||
uartinit(void)
|
uartinit(void)
|
||||||
{
|
{
|
||||||
// disable interrupts
|
// disable interrupts -- IER
|
||||||
*R(1) = 0x00;
|
*R(1) = 0x00;
|
||||||
|
|
||||||
// special mode to set baud rate
|
// special mode to set baud rate
|
||||||
|
@ -30,8 +36,11 @@ uartinit(void)
|
||||||
// and set word length to 8 bits, no parity.
|
// and set word length to 8 bits, no parity.
|
||||||
*R(3) = 0x03;
|
*R(3) = 0x03;
|
||||||
|
|
||||||
// reset and enable FIFOs.
|
// reset and enable FIFOs -- FCR.
|
||||||
*R(2) = 0x07;
|
*R(2) = 0x07;
|
||||||
|
|
||||||
|
// enable receive interrupts -- IER.
|
||||||
|
*R(1) = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -40,9 +49,11 @@ uartputc(int c)
|
||||||
*R(0) = c;
|
*R(0) = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
uint
|
||||||
uartgetc(void)
|
uartgetc(void)
|
||||||
{
|
{
|
||||||
|
// XXX this isn't right, must check there's data in the FIFO.
|
||||||
|
return *R(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
5
vm.c
5
vm.c
|
@ -30,6 +30,11 @@ kvminit()
|
||||||
mappages(kernel_pagetable, UART0, PGSIZE,
|
mappages(kernel_pagetable, UART0, PGSIZE,
|
||||||
UART0, PTE_R | PTE_W);
|
UART0, PTE_R | PTE_W);
|
||||||
|
|
||||||
|
// PLIC
|
||||||
|
mappages(kernel_pagetable, PLIC, 0x4000000,
|
||||||
|
PLIC, PTE_R | PTE_W);
|
||||||
|
|
||||||
|
|
||||||
// map kernel text executable and read-only.
|
// map kernel text executable and read-only.
|
||||||
mappages(kernel_pagetable, KERNBASE, (uint64)etext-KERNBASE,
|
mappages(kernel_pagetable, KERNBASE, (uint64)etext-KERNBASE,
|
||||||
KERNBASE, PTE_R | PTE_X);
|
KERNBASE, PTE_R | PTE_X);
|
||||||
|
|
Loading…
Reference in a new issue