Formatted *.h files

feat/start
hheik 2024-04-30 00:59:43 +03:00
parent d9faacecaf
commit 8d44d9c964
18 changed files with 555 additions and 649 deletions

View File

@ -1,12 +1,11 @@
struct buf { struct buf {
int valid; // has data been read from disk? int valid; // has data been read from disk?
int disk; // does disk "own" buf? int disk; // does disk "own" buf?
uint dev; uint dev;
uint blockno; uint blockno;
struct sleeplock lock; struct sleeplock lock;
uint refcnt; uint refcnt;
struct buf *prev; // LRU cache list struct buf *prev; // LRU cache list
struct buf *next; struct buf *next;
uchar data[BSIZE]; uchar data[BSIZE];
}; };

View File

@ -10,180 +10,180 @@ struct stat;
struct superblock; struct superblock;
// bio.c // bio.c
void binit(void); void binit(void);
struct buf* bread(uint, uint); struct buf *bread(uint, uint);
void brelse(struct buf*); void brelse(struct buf *);
void bwrite(struct buf*); void bwrite(struct buf *);
void bpin(struct buf*); void bpin(struct buf *);
void bunpin(struct buf*); void bunpin(struct buf *);
// console.c // console.c
void consoleinit(void); void consoleinit(void);
void consoleintr(int); void consoleintr(int);
void consputc(int); void consputc(int);
// exec.c // exec.c
int exec(char*, char**); int exec(char *, char **);
// file.c // file.c
struct file* filealloc(void); struct file *filealloc(void);
void fileclose(struct file*); void fileclose(struct file *);
struct file* filedup(struct file*); struct file *filedup(struct file *);
void fileinit(void); void fileinit(void);
int fileread(struct file*, uint64, int n); int fileread(struct file *, uint64, int n);
int filestat(struct file*, uint64 addr); int filestat(struct file *, uint64 addr);
int filewrite(struct file*, uint64, int n); int filewrite(struct file *, uint64, int n);
// fs.c // fs.c
void fsinit(int); void fsinit(int);
int dirlink(struct inode*, char*, uint); int dirlink(struct inode *, char *, uint);
struct inode* dirlookup(struct inode*, char*, uint*); struct inode *dirlookup(struct inode *, char *, uint *);
struct inode* ialloc(uint, short); struct inode *ialloc(uint, short);
struct inode* idup(struct inode*); struct inode *idup(struct inode *);
void iinit(); void iinit();
void ilock(struct inode*); void ilock(struct inode *);
void iput(struct inode*); void iput(struct inode *);
void iunlock(struct inode*); void iunlock(struct inode *);
void iunlockput(struct inode*); void iunlockput(struct inode *);
void iupdate(struct inode*); void iupdate(struct inode *);
int namecmp(const char*, const char*); int namecmp(const char *, const char *);
struct inode* namei(char*); struct inode *namei(char *);
struct inode* nameiparent(char*, char*); struct inode *nameiparent(char *, char *);
int readi(struct inode*, int, uint64, uint, uint); int readi(struct inode *, int, uint64, uint, uint);
void stati(struct inode*, struct stat*); void stati(struct inode *, struct stat *);
int writei(struct inode*, int, uint64, uint, uint); int writei(struct inode *, int, uint64, uint, uint);
void itrunc(struct inode*); void itrunc(struct inode *);
// ramdisk.c // ramdisk.c
void ramdiskinit(void); void ramdiskinit(void);
void ramdiskintr(void); void ramdiskintr(void);
void ramdiskrw(struct buf*); void ramdiskrw(struct buf *);
// kalloc.c // kalloc.c
void* kalloc(void); void *kalloc(void);
void kfree(void *); void kfree(void *);
void kinit(void); void kinit(void);
// log.c // log.c
void initlog(int, struct superblock*); void initlog(int, struct superblock *);
void log_write(struct buf*); void log_write(struct buf *);
void begin_op(void); void begin_op(void);
void end_op(void); void end_op(void);
// pipe.c // pipe.c
int pipealloc(struct file**, struct file**); int pipealloc(struct file **, struct file **);
void pipeclose(struct pipe*, int); void pipeclose(struct pipe *, int);
int piperead(struct pipe*, uint64, int); int piperead(struct pipe *, uint64, int);
int pipewrite(struct pipe*, uint64, int); int pipewrite(struct pipe *, uint64, int);
// printf.c // printf.c
void printf(char*, ...); void printf(char *, ...);
void panic(char*) __attribute__((noreturn)); void panic(char *) __attribute__((noreturn));
void printfinit(void); void printfinit(void);
// proc.c // proc.c
int cpuid(void); int cpuid(void);
void exit(int); void exit(int);
int fork(void); int fork(void);
int growproc(int); int growproc(int);
void proc_mapstacks(pagetable_t); void proc_mapstacks(pagetable_t);
pagetable_t proc_pagetable(struct proc *); pagetable_t proc_pagetable(struct proc *);
void proc_freepagetable(pagetable_t, uint64); void proc_freepagetable(pagetable_t, uint64);
int kill(int); int kill(int);
int killed(struct proc*); int killed(struct proc *);
void setkilled(struct proc*); void setkilled(struct proc *);
struct cpu* mycpu(void); struct cpu *mycpu(void);
struct cpu* getmycpu(void); struct cpu *getmycpu(void);
struct proc* myproc(); struct proc *myproc();
void procinit(void); void procinit(void);
void scheduler(void) __attribute__((noreturn)); void scheduler(void) __attribute__((noreturn));
void sched(void); void sched(void);
void sleep(void*, struct spinlock*); void sleep(void *, struct spinlock *);
void userinit(void); void userinit(void);
int wait(uint64); int wait(uint64);
void wakeup(void*); void wakeup(void *);
void yield(void); void yield(void);
int either_copyout(int user_dst, uint64 dst, void *src, uint64 len); int either_copyout(int user_dst, uint64 dst, void *src, uint64 len);
int either_copyin(void *dst, int user_src, uint64 src, uint64 len); int either_copyin(void *dst, int user_src, uint64 src, uint64 len);
void procdump(void); void procdump(void);
// swtch.S // swtch.S
void swtch(struct context*, struct context*); void swtch(struct context *, struct context *);
// spinlock.c // spinlock.c
void acquire(struct spinlock*); void acquire(struct spinlock *);
int holding(struct spinlock*); int holding(struct spinlock *);
void initlock(struct spinlock*, char*); void initlock(struct spinlock *, char *);
void release(struct spinlock*); void release(struct spinlock *);
void push_off(void); void push_off(void);
void pop_off(void); void pop_off(void);
// sleeplock.c // sleeplock.c
void acquiresleep(struct sleeplock*); void acquiresleep(struct sleeplock *);
void releasesleep(struct sleeplock*); void releasesleep(struct sleeplock *);
int holdingsleep(struct sleeplock*); int holdingsleep(struct sleeplock *);
void initsleeplock(struct sleeplock*, char*); void initsleeplock(struct sleeplock *, char *);
// string.c // string.c
int memcmp(const void*, const void*, uint); int memcmp(const void *, const void *, uint);
void* memmove(void*, const void*, uint); void *memmove(void *, const void *, uint);
void* memset(void*, int, uint); void *memset(void *, int, uint);
char* safestrcpy(char*, const char*, int); char *safestrcpy(char *, const char *, int);
int strlen(const char*); int strlen(const char *);
int strncmp(const char*, const char*, uint); int strncmp(const char *, const char *, uint);
char* strncpy(char*, const char*, int); char *strncpy(char *, const char *, int);
// syscall.c // syscall.c
void argint(int, int*); void argint(int, int *);
int argstr(int, char*, int); int argstr(int, char *, int);
void argaddr(int, uint64 *); void argaddr(int, uint64 *);
int fetchstr(uint64, char*, int); int fetchstr(uint64, char *, int);
int fetchaddr(uint64, uint64*); int fetchaddr(uint64, uint64 *);
void syscall(); void syscall();
// trap.c // trap.c
extern uint ticks; extern uint ticks;
void trapinit(void); void trapinit(void);
void trapinithart(void); void trapinithart(void);
extern struct spinlock tickslock; extern struct spinlock tickslock;
void usertrapret(void); void usertrapret(void);
// uart.c // uart.c
void uartinit(void); void uartinit(void);
void uartintr(void); void uartintr(void);
void uartputc(int); void uartputc(int);
void uartputc_sync(int); void uartputc_sync(int);
int uartgetc(void); int uartgetc(void);
// vm.c // vm.c
void kvminit(void); void kvminit(void);
void kvminithart(void); void kvminithart(void);
void kvmmap(pagetable_t, uint64, uint64, uint64, int); void kvmmap(pagetable_t, uint64, uint64, uint64, int);
int mappages(pagetable_t, uint64, uint64, uint64, int); int mappages(pagetable_t, uint64, uint64, uint64, int);
pagetable_t uvmcreate(void); pagetable_t uvmcreate(void);
void uvmfirst(pagetable_t, uchar *, uint); void uvmfirst(pagetable_t, uchar *, uint);
uint64 uvmalloc(pagetable_t, uint64, uint64, int); uint64 uvmalloc(pagetable_t, uint64, uint64, int);
uint64 uvmdealloc(pagetable_t, uint64, uint64); uint64 uvmdealloc(pagetable_t, uint64, uint64);
int uvmcopy(pagetable_t, pagetable_t, uint64); int uvmcopy(pagetable_t, pagetable_t, uint64);
void uvmfree(pagetable_t, uint64); void uvmfree(pagetable_t, uint64);
void uvmunmap(pagetable_t, uint64, uint64, int); void uvmunmap(pagetable_t, uint64, uint64, int);
void uvmclear(pagetable_t, uint64); void uvmclear(pagetable_t, uint64);
pte_t * walk(pagetable_t, uint64, int); pte_t *walk(pagetable_t, uint64, int);
uint64 walkaddr(pagetable_t, uint64); uint64 walkaddr(pagetable_t, uint64);
int copyout(pagetable_t, uint64, char *, uint64); int copyout(pagetable_t, uint64, char *, uint64);
int copyin(pagetable_t, char *, uint64, uint64); int copyin(pagetable_t, char *, uint64, uint64);
int copyinstr(pagetable_t, char *, uint64, uint64); int copyinstr(pagetable_t, char *, uint64, uint64);
// plic.c // plic.c
void plicinit(void); void plicinit(void);
void plicinithart(void); void plicinithart(void);
int plic_claim(void); int plic_claim(void);
void plic_complete(int); void plic_complete(int);
// virtio_disk.c // virtio_disk.c
void virtio_disk_init(void); void virtio_disk_init(void);
void virtio_disk_rw(struct buf *, int); void virtio_disk_rw(struct buf *, int);
void virtio_disk_intr(void); void virtio_disk_intr(void);
// number of elements in fixed-size array // number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0])) #define NELEM(x) (sizeof(x) / sizeof((x)[0]))

View File

@ -1,42 +1,42 @@
// Format of an ELF executable file // Format of an ELF executable file
#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian #define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian
// File header // File header
struct elfhdr { struct elfhdr {
uint magic; // must equal ELF_MAGIC uint magic; // must equal ELF_MAGIC
uchar elf[12]; uchar elf[12];
ushort type; ushort type;
ushort machine; ushort machine;
uint version; uint version;
uint64 entry; uint64 entry;
uint64 phoff; uint64 phoff;
uint64 shoff; uint64 shoff;
uint flags; uint flags;
ushort ehsize; ushort ehsize;
ushort phentsize; ushort phentsize;
ushort phnum; ushort phnum;
ushort shentsize; ushort shentsize;
ushort shnum; ushort shnum;
ushort shstrndx; ushort shstrndx;
}; };
// Program section header // Program section header
struct proghdr { struct proghdr {
uint32 type; uint32 type;
uint32 flags; uint32 flags;
uint64 off; uint64 off;
uint64 vaddr; uint64 vaddr;
uint64 paddr; uint64 paddr;
uint64 filesz; uint64 filesz;
uint64 memsz; uint64 memsz;
uint64 align; uint64 align;
}; };
// Values for Proghdr type // Values for Proghdr type
#define ELF_PROG_LOAD 1 #define ELF_PROG_LOAD 1
// Flag bits for Proghdr flags // Flag bits for Proghdr flags
#define ELF_PROG_FLAG_EXEC 1 #define ELF_PROG_FLAG_EXEC 1
#define ELF_PROG_FLAG_WRITE 2 #define ELF_PROG_FLAG_WRITE 2
#define ELF_PROG_FLAG_READ 4 #define ELF_PROG_FLAG_READ 4

View File

@ -1,5 +1,5 @@
#define O_RDONLY 0x000 #define O_RDONLY 0x000
#define O_WRONLY 0x001 #define O_WRONLY 0x001
#define O_RDWR 0x002 #define O_RDWR 0x002
#define O_CREATE 0x200 #define O_CREATE 0x200
#define O_TRUNC 0x400 #define O_TRUNC 0x400

View File

@ -1,38 +1,38 @@
struct file { struct file {
enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type; enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type;
int ref; // reference count int ref; // reference count
char readable; char readable;
char writable; char writable;
struct pipe *pipe; // FD_PIPE struct pipe *pipe; // FD_PIPE
struct inode *ip; // FD_INODE and FD_DEVICE struct inode *ip; // FD_INODE and FD_DEVICE
uint off; // FD_INODE uint off; // FD_INODE
short major; // FD_DEVICE short major; // FD_DEVICE
}; };
#define major(dev) ((dev) >> 16 & 0xFFFF) #define major(dev) ((dev) >> 16 & 0xFFFF)
#define minor(dev) ((dev) & 0xFFFF) #define minor(dev) ((dev) & 0xFFFF)
#define mkdev(m,n) ((uint)((m)<<16| (n))) #define mkdev(m, n) ((uint)((m) << 16 | (n)))
// in-memory copy of an inode // in-memory copy of an inode
struct inode { struct inode {
uint dev; // Device number uint dev; // Device number
uint inum; // Inode number uint inum; // Inode number
int ref; // Reference count int ref; // Reference count
struct sleeplock lock; // protects everything below here struct sleeplock lock; // protects everything below here
int valid; // inode has been read from disk? int valid; // inode has been read from disk?
short type; // copy of disk inode short type; // copy of disk inode
short major; short major;
short minor; short minor;
short nlink; short nlink;
uint size; uint size;
uint addrs[NDIRECT+1]; uint addrs[NDIRECT + 1];
}; };
// map major device number to device functions. // map major device number to device functions.
struct devsw { struct devsw {
int (*read)(int, uint64, int); int (*read)(int, uint64, int);
int (*write)(int, uint64, int); int (*write)(int, uint64, int);
}; };
extern struct devsw devsw[]; extern struct devsw devsw[];

View File

@ -1,9 +1,8 @@
// On-disk file system format. // On-disk file system format.
// Both the kernel and user programs use this header file. // Both the kernel and user programs use this header file.
#define ROOTINO 1 // root i-number
#define ROOTINO 1 // root i-number #define BSIZE 1024 // block size
#define BSIZE 1024 // block size
// Disk layout: // Disk layout:
// [ boot block | super block | log | inode blocks | // [ boot block | super block | log | inode blocks |
@ -12,14 +11,14 @@
// mkfs computes the super block and builds an initial file system. The // mkfs computes the super block and builds an initial file system. The
// super block describes the disk layout: // super block describes the disk layout:
struct superblock { struct superblock {
uint magic; // Must be FSMAGIC uint magic; // Must be FSMAGIC
uint size; // Size of file system image (blocks) uint size; // Size of file system image (blocks)
uint nblocks; // Number of data blocks uint nblocks; // Number of data blocks
uint ninodes; // Number of inodes. uint ninodes; // Number of inodes.
uint nlog; // Number of log blocks uint nlog; // Number of log blocks
uint logstart; // Block number of first log block uint logstart; // Block number of first log block
uint inodestart; // Block number of first inode block uint inodestart; // Block number of first inode block
uint bmapstart; // Block number of first free map block uint bmapstart; // Block number of first free map block
}; };
#define FSMAGIC 0x10203040 #define FSMAGIC 0x10203040
@ -30,31 +29,30 @@ struct superblock {
// On-disk inode structure // On-disk inode structure
struct dinode { struct dinode {
short type; // File type short type; // File type
short major; // Major device number (T_DEVICE only) short major; // Major device number (T_DEVICE only)
short minor; // Minor device number (T_DEVICE only) short minor; // Minor device number (T_DEVICE only)
short nlink; // Number of links to inode in file system short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes) uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses uint addrs[NDIRECT + 1]; // Data block addresses
}; };
// Inodes per block. // Inodes per block.
#define IPB (BSIZE / sizeof(struct dinode)) #define IPB (BSIZE / sizeof(struct dinode))
// Block containing inode i // Block containing inode i
#define IBLOCK(i, sb) ((i) / IPB + sb.inodestart) #define IBLOCK(i, sb) ((i) / IPB + sb.inodestart)
// Bitmap bits per block // Bitmap bits per block
#define BPB (BSIZE*8) #define BPB (BSIZE * 8)
// Block of free map containing bit for block b // Block of free map containing bit for block b
#define BBLOCK(b, sb) ((b)/BPB + sb.bmapstart) #define BBLOCK(b, sb) ((b) / BPB + sb.bmapstart)
// Directory is a file containing a sequence of dirent structures. // Directory is a file containing a sequence of dirent structures.
#define DIRSIZ 14 #define DIRSIZ 14
struct dirent { struct dirent {
ushort inum; ushort inum;
char name[DIRSIZ]; char name[DIRSIZ];
}; };

View File

@ -3,9 +3,7 @@
#include "memlayout.h" #include "memlayout.h"
#include "riscv.h" #include "riscv.h"
#include "defs.h" #include "defs.h"
#include <stdint.h> #include "rust.h"
extern int32_t add(int32_t right, int32_t left);
volatile static int started = 0; volatile static int started = 0;

View File

@ -27,25 +27,25 @@
// core local interruptor (CLINT), which contains the timer. // core local interruptor (CLINT), which contains the timer.
#define CLINT 0x2000000L #define CLINT 0x2000000L
#define CLINT_MTIMECMP(hartid) (CLINT + 0x4000 + 8*(hartid)) #define CLINT_MTIMECMP(hartid) (CLINT + 0x4000 + 8 * (hartid))
#define CLINT_MTIME (CLINT + 0xBFF8) // cycles since boot. #define CLINT_MTIME (CLINT + 0xBFF8) // cycles since boot.
// qemu puts platform-level interrupt controller (PLIC) here. // qemu puts platform-level interrupt controller (PLIC) here.
#define PLIC 0x0c000000L #define PLIC 0x0c000000L
#define PLIC_PRIORITY (PLIC + 0x0) #define PLIC_PRIORITY (PLIC + 0x0)
#define PLIC_PENDING (PLIC + 0x1000) #define PLIC_PENDING (PLIC + 0x1000)
#define PLIC_MENABLE(hart) (PLIC + 0x2000 + (hart)*0x100) #define PLIC_MENABLE(hart) (PLIC + 0x2000 + (hart) * 0x100)
#define PLIC_SENABLE(hart) (PLIC + 0x2080 + (hart)*0x100) #define PLIC_SENABLE(hart) (PLIC + 0x2080 + (hart) * 0x100)
#define PLIC_MPRIORITY(hart) (PLIC + 0x200000 + (hart)*0x2000) #define PLIC_MPRIORITY(hart) (PLIC + 0x200000 + (hart) * 0x2000)
#define PLIC_SPRIORITY(hart) (PLIC + 0x201000 + (hart)*0x2000) #define PLIC_SPRIORITY(hart) (PLIC + 0x201000 + (hart) * 0x2000)
#define PLIC_MCLAIM(hart) (PLIC + 0x200004 + (hart)*0x2000) #define PLIC_MCLAIM(hart) (PLIC + 0x200004 + (hart) * 0x2000)
#define PLIC_SCLAIM(hart) (PLIC + 0x201004 + (hart)*0x2000) #define PLIC_SCLAIM(hart) (PLIC + 0x201004 + (hart) * 0x2000)
// the kernel expects there to be RAM // the kernel expects there to be RAM
// for use by the kernel and user pages // for use by the kernel and user pages
// from physical address 0x80000000 to PHYSTOP. // from physical address 0x80000000 to PHYSTOP.
#define KERNBASE 0x80000000L #define KERNBASE 0x80000000L
#define PHYSTOP (KERNBASE + 128*1024*1024) #define PHYSTOP (KERNBASE + 128 * 1024 * 1024)
// map the trampoline page to the highest address, // map the trampoline page to the highest address,
// in both user and kernel space. // in both user and kernel space.
@ -53,7 +53,7 @@
// map kernel stacks beneath the trampoline, // map kernel stacks beneath the trampoline,
// each surrounded by invalid guard pages. // each surrounded by invalid guard pages.
#define KSTACK(p) (TRAMPOLINE - ((p)+1)* 2*PGSIZE) #define KSTACK(p) (TRAMPOLINE - ((p) + 1) * 2 * PGSIZE)
// User memory layout. // User memory layout.
// Address zero first: // Address zero first:

View File

@ -1,13 +1,13 @@
#define NPROC 64 // maximum number of processes #define NPROC 64 // maximum number of processes
#define NCPU 8 // maximum number of CPUs #define NCPU 8 // maximum number of CPUs
#define NOFILE 16 // open files per process #define NOFILE 16 // open files per process
#define NFILE 100 // open files per system #define NFILE 100 // open files per system
#define NINODE 50 // maximum number of active i-nodes #define NINODE 50 // maximum number of active i-nodes
#define NDEV 10 // maximum major device number #define NDEV 10 // maximum major device number
#define ROOTDEV 1 // device number of file system root disk #define ROOTDEV 1 // device number of file system root disk
#define MAXARG 32 // max exec arguments #define MAXARG 32 // max exec arguments
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes #define MAXOPBLOCKS 10 // max # of blocks any FS op writes
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log #define LOGSIZE (MAXOPBLOCKS * 3) // max data blocks in on-disk log
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache #define NBUF (MAXOPBLOCKS * 3) // size of disk block cache
#define FSSIZE 2000 // size of file system in blocks #define FSSIZE 2000 // size of file system in blocks
#define MAXPATH 128 // maximum file path name #define MAXPATH 128 // maximum file path name

View File

@ -1,29 +1,29 @@
// Saved registers for kernel context switches. // Saved registers for kernel context switches.
struct context { struct context {
uint64 ra; uint64 ra;
uint64 sp; uint64 sp;
// callee-saved // callee-saved
uint64 s0; uint64 s0;
uint64 s1; uint64 s1;
uint64 s2; uint64 s2;
uint64 s3; uint64 s3;
uint64 s4; uint64 s4;
uint64 s5; uint64 s5;
uint64 s6; uint64 s6;
uint64 s7; uint64 s7;
uint64 s8; uint64 s8;
uint64 s9; uint64 s9;
uint64 s10; uint64 s10;
uint64 s11; uint64 s11;
}; };
// Per-CPU state. // Per-CPU state.
struct cpu { struct cpu {
struct proc *proc; // The process running on this cpu, or null. struct proc *proc; // The process running on this cpu, or null.
struct context context; // swtch() here to enter scheduler(). struct context context; // swtch() here to enter scheduler().
int noff; // Depth of push_off() nesting. int noff; // Depth of push_off() nesting.
int intena; // Were interrupts enabled before push_off()? int intena; // Were interrupts enabled before push_off()?
}; };
extern struct cpu cpus[NCPU]; extern struct cpu cpus[NCPU];
@ -41,67 +41,67 @@ extern struct cpu cpus[NCPU];
// return-to-user path via usertrapret() doesn't return through // return-to-user path via usertrapret() doesn't return through
// the entire kernel call stack. // the entire kernel call stack.
struct trapframe { struct trapframe {
/* 0 */ uint64 kernel_satp; // kernel page table /* 0 */ uint64 kernel_satp; // kernel page table
/* 8 */ uint64 kernel_sp; // top of process's kernel stack /* 8 */ uint64 kernel_sp; // top of process's kernel stack
/* 16 */ uint64 kernel_trap; // usertrap() /* 16 */ uint64 kernel_trap; // usertrap()
/* 24 */ uint64 epc; // saved user program counter /* 24 */ uint64 epc; // saved user program counter
/* 32 */ uint64 kernel_hartid; // saved kernel tp /* 32 */ uint64 kernel_hartid; // saved kernel tp
/* 40 */ uint64 ra; /* 40 */ uint64 ra;
/* 48 */ uint64 sp; /* 48 */ uint64 sp;
/* 56 */ uint64 gp; /* 56 */ uint64 gp;
/* 64 */ uint64 tp; /* 64 */ uint64 tp;
/* 72 */ uint64 t0; /* 72 */ uint64 t0;
/* 80 */ uint64 t1; /* 80 */ uint64 t1;
/* 88 */ uint64 t2; /* 88 */ uint64 t2;
/* 96 */ uint64 s0; /* 96 */ uint64 s0;
/* 104 */ uint64 s1; /* 104 */ uint64 s1;
/* 112 */ uint64 a0; /* 112 */ uint64 a0;
/* 120 */ uint64 a1; /* 120 */ uint64 a1;
/* 128 */ uint64 a2; /* 128 */ uint64 a2;
/* 136 */ uint64 a3; /* 136 */ uint64 a3;
/* 144 */ uint64 a4; /* 144 */ uint64 a4;
/* 152 */ uint64 a5; /* 152 */ uint64 a5;
/* 160 */ uint64 a6; /* 160 */ uint64 a6;
/* 168 */ uint64 a7; /* 168 */ uint64 a7;
/* 176 */ uint64 s2; /* 176 */ uint64 s2;
/* 184 */ uint64 s3; /* 184 */ uint64 s3;
/* 192 */ uint64 s4; /* 192 */ uint64 s4;
/* 200 */ uint64 s5; /* 200 */ uint64 s5;
/* 208 */ uint64 s6; /* 208 */ uint64 s6;
/* 216 */ uint64 s7; /* 216 */ uint64 s7;
/* 224 */ uint64 s8; /* 224 */ uint64 s8;
/* 232 */ uint64 s9; /* 232 */ uint64 s9;
/* 240 */ uint64 s10; /* 240 */ uint64 s10;
/* 248 */ uint64 s11; /* 248 */ uint64 s11;
/* 256 */ uint64 t3; /* 256 */ uint64 t3;
/* 264 */ uint64 t4; /* 264 */ uint64 t4;
/* 272 */ uint64 t5; /* 272 */ uint64 t5;
/* 280 */ uint64 t6; /* 280 */ uint64 t6;
}; };
enum procstate { UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; enum procstate { UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state // Per-process state
struct proc { struct proc {
struct spinlock lock; struct spinlock lock;
// p->lock must be held when using these: // p->lock must be held when using these:
enum procstate state; // Process state enum procstate state; // Process state
void *chan; // If non-zero, sleeping on chan void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed int killed; // If non-zero, have been killed
int xstate; // Exit status to be returned to parent's wait int xstate; // Exit status to be returned to parent's wait
int pid; // Process ID int pid; // Process ID
// wait_lock must be held when using this: // wait_lock must be held when using this:
struct proc *parent; // Parent process struct proc *parent; // Parent process
// these are private to the process, so p->lock need not be held. // these are private to the process, so p->lock need not be held.
uint64 kstack; // Virtual address of kernel stack uint64 kstack; // Virtual address of kernel stack
uint64 sz; // Size of process memory (bytes) uint64 sz; // Size of process memory (bytes)
pagetable_t pagetable; // User page table pagetable_t pagetable; // User page table
struct trapframe *trapframe; // data page for trampoline.S struct trapframe *trapframe; // data page for trampoline.S
struct context context; // swtch() here to run process struct context context; // swtch() here to run process
struct file *ofile[NOFILE]; // Open files struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory struct inode *cwd; // Current directory
char name[16]; // Process name (debugging) char name[16]; // Process name (debugging)
}; };

View File

@ -1,12 +1,10 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
// which hart (core) is this? // which hart (core) is this?
static inline uint64 static inline uint64 r_mhartid() {
r_mhartid() uint64 x;
{ asm volatile("csrr %0, mhartid" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, mhartid" : "=r" (x) );
return x;
} }
// Machine Status Register, mstatus // Machine Status Register, mstatus
@ -15,29 +13,23 @@ r_mhartid()
#define MSTATUS_MPP_M (3L << 11) #define MSTATUS_MPP_M (3L << 11)
#define MSTATUS_MPP_S (1L << 11) #define MSTATUS_MPP_S (1L << 11)
#define MSTATUS_MPP_U (0L << 11) #define MSTATUS_MPP_U (0L << 11)
#define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable. #define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable.
static inline uint64 static inline uint64 r_mstatus() {
r_mstatus() uint64 x;
{ asm volatile("csrr %0, mstatus" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, mstatus" : "=r" (x) );
return x;
} }
static inline void static inline void w_mstatus(uint64 x) {
w_mstatus(uint64 x) asm volatile("csrw mstatus, %0" : : "r"(x));
{
asm volatile("csrw mstatus, %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.
static inline void static inline void w_mepc(uint64 x) {
w_mepc(uint64 x) asm volatile("csrw mepc, %0" : : "r"(x));
{
asm volatile("csrw mepc, %0" : : "r" (x));
} }
// Supervisor Status Register, sstatus // Supervisor Status Register, sstatus
@ -48,152 +40,108 @@ w_mepc(uint64 x)
#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable #define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
#define SSTATUS_UIE (1L << 0) // User Interrupt Enable #define SSTATUS_UIE (1L << 0) // User Interrupt Enable
static inline uint64 static inline uint64 r_sstatus() {
r_sstatus() uint64 x;
{ asm volatile("csrr %0, sstatus" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, sstatus" : "=r" (x) );
return x;
} }
static inline void static inline void w_sstatus(uint64 x) {
w_sstatus(uint64 x) asm volatile("csrw sstatus, %0" : : "r"(x));
{
asm volatile("csrw sstatus, %0" : : "r" (x));
} }
// Supervisor Interrupt Pending // Supervisor Interrupt Pending
static inline uint64 static inline uint64 r_sip() {
r_sip() uint64 x;
{ asm volatile("csrr %0, sip" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, sip" : "=r" (x) );
return x;
} }
static inline void static inline void w_sip(uint64 x) { asm volatile("csrw sip, %0" : : "r"(x)); }
w_sip(uint64 x)
{
asm volatile("csrw sip, %0" : : "r" (x));
}
// Supervisor Interrupt Enable // Supervisor Interrupt Enable
#define SIE_SEIE (1L << 9) // external #define SIE_SEIE (1L << 9) // external
#define SIE_STIE (1L << 5) // timer #define SIE_STIE (1L << 5) // timer
#define SIE_SSIE (1L << 1) // software #define SIE_SSIE (1L << 1) // software
static inline uint64 static inline uint64 r_sie() {
r_sie() uint64 x;
{ asm volatile("csrr %0, sie" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, sie" : "=r" (x) );
return x;
} }
static inline void static inline void w_sie(uint64 x) { asm volatile("csrw sie, %0" : : "r"(x)); }
w_sie(uint64 x)
{
asm volatile("csrw sie, %0" : : "r" (x));
}
// Machine-mode Interrupt Enable // Machine-mode Interrupt Enable
#define MIE_MEIE (1L << 11) // external #define MIE_MEIE (1L << 11) // external
#define MIE_MTIE (1L << 7) // timer #define MIE_MTIE (1L << 7) // timer
#define MIE_MSIE (1L << 3) // software #define MIE_MSIE (1L << 3) // software
static inline uint64 static inline uint64 r_mie() {
r_mie() uint64 x;
{ asm volatile("csrr %0, mie" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, mie" : "=r" (x) );
return x;
} }
static inline void static inline void w_mie(uint64 x) { asm volatile("csrw mie, %0" : : "r"(x)); }
w_mie(uint64 x)
{
asm volatile("csrw mie, %0" : : "r" (x));
}
// supervisor exception program counter, holds the // supervisor 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.
static inline void static inline void w_sepc(uint64 x) {
w_sepc(uint64 x) asm volatile("csrw sepc, %0" : : "r"(x));
{
asm volatile("csrw sepc, %0" : : "r" (x));
} }
static inline uint64 static inline uint64 r_sepc() {
r_sepc() uint64 x;
{ asm volatile("csrr %0, sepc" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, sepc" : "=r" (x) );
return x;
} }
// Machine Exception Delegation // Machine Exception Delegation
static inline uint64 static inline uint64 r_medeleg() {
r_medeleg() uint64 x;
{ asm volatile("csrr %0, medeleg" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, medeleg" : "=r" (x) );
return x;
} }
static inline void static inline void w_medeleg(uint64 x) {
w_medeleg(uint64 x) asm volatile("csrw medeleg, %0" : : "r"(x));
{
asm volatile("csrw medeleg, %0" : : "r" (x));
} }
// Machine Interrupt Delegation // Machine Interrupt Delegation
static inline uint64 static inline uint64 r_mideleg() {
r_mideleg() uint64 x;
{ asm volatile("csrr %0, mideleg" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, mideleg" : "=r" (x) );
return x;
} }
static inline void static inline void w_mideleg(uint64 x) {
w_mideleg(uint64 x) asm volatile("csrw mideleg, %0" : : "r"(x));
{
asm volatile("csrw mideleg, %0" : : "r" (x));
} }
// Supervisor Trap-Vector Base Address // Supervisor Trap-Vector Base Address
// low two bits are mode. // low two bits are mode.
static inline void static inline void w_stvec(uint64 x) {
w_stvec(uint64 x) asm volatile("csrw stvec, %0" : : "r"(x));
{
asm volatile("csrw stvec, %0" : : "r" (x));
} }
static inline uint64 static inline uint64 r_stvec() {
r_stvec() uint64 x;
{ asm volatile("csrr %0, stvec" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, stvec" : "=r" (x) );
return x;
} }
// Machine-mode interrupt vector // Machine-mode interrupt vector
static inline void static inline void w_mtvec(uint64 x) {
w_mtvec(uint64 x) asm volatile("csrw mtvec, %0" : : "r"(x));
{
asm volatile("csrw mtvec, %0" : : "r" (x));
} }
// Physical Memory Protection // Physical Memory Protection
static inline void static inline void w_pmpcfg0(uint64 x) {
w_pmpcfg0(uint64 x) asm volatile("csrw pmpcfg0, %0" : : "r"(x));
{
asm volatile("csrw pmpcfg0, %0" : : "r" (x));
} }
static inline void static inline void w_pmpaddr0(uint64 x) {
w_pmpaddr0(uint64 x) asm volatile("csrw pmpaddr0, %0" : : "r"(x));
{
asm volatile("csrw pmpaddr0, %0" : : "r" (x));
} }
// use riscv's sv39 page table scheme. // use riscv's sv39 page table scheme.
@ -203,128 +151,90 @@ w_pmpaddr0(uint64 x)
// supervisor address translation and protection; // supervisor address translation and protection;
// holds the address of the page table. // holds the address of the page table.
static inline void static inline void w_satp(uint64 x) {
w_satp(uint64 x) asm volatile("csrw satp, %0" : : "r"(x));
{
asm volatile("csrw satp, %0" : : "r" (x));
} }
static inline uint64 static inline uint64 r_satp() {
r_satp() uint64 x;
{ asm volatile("csrr %0, satp" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, satp" : "=r" (x) );
return x;
} }
static inline void static inline void w_mscratch(uint64 x) {
w_mscratch(uint64 x) asm volatile("csrw mscratch, %0" : : "r"(x));
{
asm volatile("csrw mscratch, %0" : : "r" (x));
} }
// Supervisor Trap Cause // Supervisor Trap Cause
static inline uint64 static inline uint64 r_scause() {
r_scause() uint64 x;
{ asm volatile("csrr %0, scause" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, scause" : "=r" (x) );
return x;
} }
// Supervisor Trap Value // Supervisor Trap Value
static inline uint64 static inline uint64 r_stval() {
r_stval() uint64 x;
{ asm volatile("csrr %0, stval" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, stval" : "=r" (x) );
return x;
} }
// Machine-mode Counter-Enable // Machine-mode Counter-Enable
static inline void static inline void w_mcounteren(uint64 x) {
w_mcounteren(uint64 x) asm volatile("csrw mcounteren, %0" : : "r"(x));
{
asm volatile("csrw mcounteren, %0" : : "r" (x));
} }
static inline uint64 static inline uint64 r_mcounteren() {
r_mcounteren() uint64 x;
{ asm volatile("csrr %0, mcounteren" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, mcounteren" : "=r" (x) );
return x;
} }
// machine-mode cycle counter // machine-mode cycle counter
static inline uint64 static inline uint64 r_time() {
r_time() uint64 x;
{ asm volatile("csrr %0, time" : "=r"(x));
uint64 x; return x;
asm volatile("csrr %0, time" : "=r" (x) );
return x;
} }
// enable device interrupts // enable device interrupts
static inline void static inline void intr_on() { w_sstatus(r_sstatus() | SSTATUS_SIE); }
intr_on()
{
w_sstatus(r_sstatus() | SSTATUS_SIE);
}
// disable device interrupts // disable device interrupts
static inline void static inline void intr_off() { w_sstatus(r_sstatus() & ~SSTATUS_SIE); }
intr_off()
{
w_sstatus(r_sstatus() & ~SSTATUS_SIE);
}
// are device interrupts enabled? // are device interrupts enabled?
static inline int static inline int intr_get() {
intr_get() uint64 x = r_sstatus();
{ return (x & SSTATUS_SIE) != 0;
uint64 x = r_sstatus();
return (x & SSTATUS_SIE) != 0;
} }
static inline uint64 static inline uint64 r_sp() {
r_sp() uint64 x;
{ asm volatile("mv %0, sp" : "=r"(x));
uint64 x; return x;
asm volatile("mv %0, sp" : "=r" (x) );
return x;
} }
// read and write tp, the thread pointer, which xv6 uses to hold // read and write tp, the thread pointer, which xv6 uses to hold
// this core's hartid (core number), the index into cpus[]. // this core's hartid (core number), the index into cpus[].
static inline uint64 static inline uint64 r_tp() {
r_tp() uint64 x;
{ asm volatile("mv %0, tp" : "=r"(x));
uint64 x; return x;
asm volatile("mv %0, tp" : "=r" (x) );
return x;
} }
static inline void static inline void w_tp(uint64 x) { asm volatile("mv tp, %0" : : "r"(x)); }
w_tp(uint64 x)
{
asm volatile("mv tp, %0" : : "r" (x));
}
static inline uint64 static inline uint64 r_ra() {
r_ra() uint64 x;
{ asm volatile("mv %0, ra" : "=r"(x));
uint64 x; return x;
asm volatile("mv %0, ra" : "=r" (x) );
return x;
} }
// flush the TLB. // flush the TLB.
static inline void static inline void sfence_vma() {
sfence_vma() // the zero, zero means flush all TLB entries.
{ asm volatile("sfence.vma zero, zero");
// the zero, zero means flush all TLB entries.
asm volatile("sfence.vma zero, zero");
} }
typedef uint64 pte_t; typedef uint64 pte_t;
@ -333,10 +243,10 @@ typedef uint64 *pagetable_t; // 512 PTEs
#endif // __ASSEMBLER__ #endif // __ASSEMBLER__
#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
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) #define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1))
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE - 1))
#define PTE_V (1L << 0) // valid #define PTE_V (1L << 0) // valid
#define PTE_R (1L << 1) #define PTE_R (1L << 1)
@ -352,9 +262,9 @@ typedef uint64 *pagetable_t; // 512 PTEs
#define PTE_FLAGS(pte) ((pte) & 0x3FF) #define PTE_FLAGS(pte) ((pte) & 0x3FF)
// extract the three 9-bit page table indices from a virtual address. // extract the three 9-bit page table indices from a virtual address.
#define PXMASK 0x1FF // 9 bits #define PXMASK 0x1FF // 9 bits
#define PXSHIFT(level) (PGSHIFT+(9*(level))) #define PXSHIFT(level) (PGSHIFT + (9 * (level)))
#define PX(level, va) ((((uint64) (va)) >> PXSHIFT(level)) & PXMASK) #define PX(level, va) ((((uint64)(va)) >> PXSHIFT(level)) & PXMASK)
// one beyond the highest possible virtual address. // one beyond the highest possible virtual address.
// MAXVA is actually one bit less than the max allowed by // MAXVA is actually one bit less than the max allowed by

View File

@ -1,10 +1,9 @@
// Long-term locks for processes // Long-term locks for processes
struct sleeplock { struct sleeplock {
uint locked; // Is the lock held? uint locked; // Is the lock held?
struct spinlock lk; // spinlock protecting this sleep lock struct spinlock lk; // spinlock protecting this sleep lock
// For debugging: // For debugging:
char *name; // Name of lock. char *name; // Name of lock.
int pid; // Process holding lock int pid; // Process holding lock
}; };

View File

@ -1,9 +1,8 @@
// Mutual exclusion lock. // Mutual exclusion lock.
struct spinlock { struct spinlock {
uint locked; // Is the lock held? uint locked; // Is the lock held?
// For debugging: // For debugging:
char *name; // Name of lock. char *name; // Name of lock.
struct cpu *cpu; // The cpu holding the lock. struct cpu *cpu; // The cpu holding the lock.
}; };

View File

@ -1,11 +1,11 @@
#define T_DIR 1 // Directory #define T_DIR 1 // Directory
#define T_FILE 2 // File #define T_FILE 2 // File
#define T_DEVICE 3 // Device #define T_DEVICE 3 // Device
struct stat { struct stat {
int dev; // File system's disk device int dev; // File system's disk device
uint ino; // Inode number uint ino; // Inode number
short type; // Type of file short type; // Type of file
short nlink; // Number of links to file short nlink; // Number of links to file
uint64 size; // Size of file in bytes uint64 size; // Size of file in bytes
}; };

View File

@ -1,22 +1,22 @@
// System call numbers // System call numbers
#define SYS_fork 1 #define SYS_fork 1
#define SYS_exit 2 #define SYS_exit 2
#define SYS_wait 3 #define SYS_wait 3
#define SYS_pipe 4 #define SYS_pipe 4
#define SYS_read 5 #define SYS_read 5
#define SYS_kill 6 #define SYS_kill 6
#define SYS_exec 7 #define SYS_exec 7
#define SYS_fstat 8 #define SYS_fstat 8
#define SYS_chdir 9 #define SYS_chdir 9
#define SYS_dup 10 #define SYS_dup 10
#define SYS_getpid 11 #define SYS_getpid 11
#define SYS_sbrk 12 #define SYS_sbrk 12
#define SYS_sleep 13 #define SYS_sleep 13
#define SYS_uptime 14 #define SYS_uptime 14
#define SYS_open 15 #define SYS_open 15
#define SYS_write 16 #define SYS_write 16
#define SYS_mknod 17 #define SYS_mknod 17
#define SYS_unlink 18 #define SYS_unlink 18
#define SYS_link 19 #define SYS_link 19
#define SYS_mkdir 20 #define SYS_mkdir 20
#define SYS_close 21 #define SYS_close 21

View File

@ -1,10 +1,10 @@
typedef unsigned int uint; typedef unsigned int uint;
typedef unsigned short ushort; typedef unsigned short ushort;
typedef unsigned char uchar; typedef unsigned char uchar;
typedef unsigned char uint8; typedef unsigned char uint8;
typedef unsigned short uint16; typedef unsigned short uint16;
typedef unsigned int uint32; typedef unsigned int uint32;
typedef unsigned long uint64; typedef unsigned long uint64;
typedef uint64 pde_t; typedef uint64 pde_t;

View File

@ -9,41 +9,44 @@
// virtio mmio control registers, mapped starting at 0x10001000. // virtio mmio control registers, mapped starting at 0x10001000.
// from qemu virtio_mmio.h // from qemu virtio_mmio.h
#define VIRTIO_MMIO_MAGIC_VALUE 0x000 // 0x74726976 #define VIRTIO_MMIO_MAGIC_VALUE 0x000 // 0x74726976
#define VIRTIO_MMIO_VERSION 0x004 // version; should be 2 #define VIRTIO_MMIO_VERSION 0x004 // version; should be 2
#define VIRTIO_MMIO_DEVICE_ID 0x008 // device type; 1 is net, 2 is disk #define VIRTIO_MMIO_DEVICE_ID 0x008 // device type; 1 is net, 2 is disk
#define VIRTIO_MMIO_VENDOR_ID 0x00c // 0x554d4551 #define VIRTIO_MMIO_VENDOR_ID 0x00c // 0x554d4551
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010 #define VIRTIO_MMIO_DEVICE_FEATURES 0x010
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 #define VIRTIO_MMIO_DRIVER_FEATURES 0x020
#define VIRTIO_MMIO_QUEUE_SEL 0x030 // select queue, write-only #define VIRTIO_MMIO_QUEUE_SEL 0x030 // select queue, write-only
#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 // max size of current queue, read-only #define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 // max size of current queue, read-only
#define VIRTIO_MMIO_QUEUE_NUM 0x038 // size of current queue, write-only #define VIRTIO_MMIO_QUEUE_NUM 0x038 // size of current queue, write-only
#define VIRTIO_MMIO_QUEUE_READY 0x044 // ready bit #define VIRTIO_MMIO_QUEUE_READY 0x044 // ready bit
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 // write-only #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 // write-only
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 // read-only #define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 // read-only
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 // write-only #define VIRTIO_MMIO_INTERRUPT_ACK 0x064 // write-only
#define VIRTIO_MMIO_STATUS 0x070 // read/write #define VIRTIO_MMIO_STATUS 0x070 // read/write
#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 // physical address for descriptor table, write-only #define VIRTIO_MMIO_QUEUE_DESC_LOW \
#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 0x080 // physical address for descriptor table, write-only
#define VIRTIO_MMIO_DRIVER_DESC_LOW 0x090 // physical address for available ring, write-only #define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
#define VIRTIO_MMIO_DRIVER_DESC_HIGH 0x094 #define VIRTIO_MMIO_DRIVER_DESC_LOW \
#define VIRTIO_MMIO_DEVICE_DESC_LOW 0x0a0 // physical address for used ring, write-only 0x090 // physical address for available ring, write-only
#define VIRTIO_MMIO_DEVICE_DESC_HIGH 0x0a4 #define VIRTIO_MMIO_DRIVER_DESC_HIGH 0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW \
0x0a0 // physical address for used ring, write-only
#define VIRTIO_MMIO_DEVICE_DESC_HIGH 0x0a4
// status register bits, from qemu virtio_config.h // status register bits, from qemu virtio_config.h
#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
#define VIRTIO_CONFIG_S_DRIVER 2 #define VIRTIO_CONFIG_S_DRIVER 2
#define VIRTIO_CONFIG_S_DRIVER_OK 4 #define VIRTIO_CONFIG_S_DRIVER_OK 4
#define VIRTIO_CONFIG_S_FEATURES_OK 8 #define VIRTIO_CONFIG_S_FEATURES_OK 8
// device feature bits // device feature bits
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ #define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */ #define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ #define VIRTIO_BLK_F_MQ 12 /* support more than one vq */
#define VIRTIO_F_ANY_LAYOUT 27 #define VIRTIO_F_ANY_LAYOUT 27
#define VIRTIO_RING_F_INDIRECT_DESC 28 #define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX 29 #define VIRTIO_RING_F_EVENT_IDX 29
// this many virtio descriptors. // this many virtio descriptors.
// must be a power of two. // must be a power of two.
@ -51,46 +54,46 @@
// a single descriptor, from the spec. // a single descriptor, from the spec.
struct virtq_desc { struct virtq_desc {
uint64 addr; uint64 addr;
uint32 len; uint32 len;
uint16 flags; uint16 flags;
uint16 next; uint16 next;
}; };
#define VRING_DESC_F_NEXT 1 // chained with another descriptor #define VRING_DESC_F_NEXT 1 // chained with another descriptor
#define VRING_DESC_F_WRITE 2 // device writes (vs read) #define VRING_DESC_F_WRITE 2 // device writes (vs read)
// the (entire) avail ring, from the spec. // the (entire) avail ring, from the spec.
struct virtq_avail { struct virtq_avail {
uint16 flags; // always zero uint16 flags; // always zero
uint16 idx; // driver will write ring[idx] next uint16 idx; // driver will write ring[idx] next
uint16 ring[NUM]; // descriptor numbers of chain heads uint16 ring[NUM]; // descriptor numbers of chain heads
uint16 unused; uint16 unused;
}; };
// one entry in the "used" ring, with which the // one entry in the "used" ring, with which the
// device tells the driver about completed requests. // device tells the driver about completed requests.
struct virtq_used_elem { struct virtq_used_elem {
uint32 id; // index of start of completed descriptor chain uint32 id; // index of start of completed descriptor chain
uint32 len; uint32 len;
}; };
struct virtq_used { struct virtq_used {
uint16 flags; // always zero uint16 flags; // always zero
uint16 idx; // device increments when it adds a ring[] entry uint16 idx; // device increments when it adds a ring[] entry
struct virtq_used_elem ring[NUM]; struct virtq_used_elem ring[NUM];
}; };
// these are specific to virtio block devices, e.g. disks, // these are specific to virtio block devices, e.g. disks,
// described in Section 5.2 of the spec. // described in Section 5.2 of the spec.
#define VIRTIO_BLK_T_IN 0 // read the disk #define VIRTIO_BLK_T_IN 0 // read the disk
#define VIRTIO_BLK_T_OUT 1 // write the disk #define VIRTIO_BLK_T_OUT 1 // write the disk
// the format of the first descriptor in a disk request. // the format of the first descriptor in a disk request.
// to be followed by two more descriptors containing // to be followed by two more descriptors containing
// the block, and a one-byte status. // the block, and a one-byte status.
struct virtio_blk_req { struct virtio_blk_req {
uint32 type; // VIRTIO_BLK_T_IN or ..._OUT uint32 type; // VIRTIO_BLK_T_IN or ..._OUT
uint32 reserved; uint32 reserved;
uint64 sector; uint64 sector;
}; };

View File

@ -3,39 +3,39 @@ struct stat;
// system calls // system calls
int fork(void); int fork(void);
int exit(int) __attribute__((noreturn)); int exit(int) __attribute__((noreturn));
int wait(int*); int wait(int *);
int pipe(int*); int pipe(int *);
int write(int, const void*, int); int write(int, const void *, int);
int read(int, void*, int); int read(int, void *, int);
int close(int); int close(int);
int kill(int); int kill(int);
int exec(const char*, char**); int exec(const char *, char **);
int open(const char*, int); int open(const char *, int);
int mknod(const char*, short, short); int mknod(const char *, short, short);
int unlink(const char*); int unlink(const char *);
int fstat(int fd, struct stat*); int fstat(int fd, struct stat *);
int link(const char*, const char*); int link(const char *, const char *);
int mkdir(const char*); int mkdir(const char *);
int chdir(const char*); int chdir(const char *);
int dup(int); int dup(int);
int getpid(void); int getpid(void);
char* sbrk(int); char *sbrk(int);
int sleep(int); int sleep(int);
int uptime(void); int uptime(void);
// ulib.c // ulib.c
int stat(const char*, struct stat*); int stat(const char *, struct stat *);
char* strcpy(char*, const char*); char *strcpy(char *, const char *);
void *memmove(void*, const void*, int); void *memmove(void *, const void *, int);
char* strchr(const char*, char c); char *strchr(const char *, char c);
int strcmp(const char*, const char*); int strcmp(const char *, const char *);
void fprintf(int, const char*, ...); void fprintf(int, const char *, ...);
void printf(const char*, ...); void printf(const char *, ...);
char* gets(char*, int max); char *gets(char *, int max);
uint strlen(const char*); uint strlen(const char *);
void* memset(void*, int, uint); void *memset(void *, int, uint);
void* malloc(uint); void *malloc(uint);
void free(void*); void free(void *);
int atoi(const char*); int atoi(const char *);
int memcmp(const void *, const void *, uint); int memcmp(const void *, const void *, uint);
void *memcpy(void *, const void *, uint); void *memcpy(void *, const void *, uint);