takes one uart input interrupt, then panics
This commit is contained in:
		
							parent
							
								
									50cbc75102
								
							
						
					
					
						commit
						a9c1a6f742
					
				
					 6 changed files with 108 additions and 6 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Robert Morris
						Robert Morris