Formatted *.h files
parent
d9faacecaf
commit
8d44d9c964
19
kernel/buf.h
19
kernel/buf.h
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
268
kernel/defs.h
268
kernel/defs.h
|
|
@ -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]))
|
||||||
|
|
|
||||||
56
kernel/elf.h
56
kernel/elf.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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[];
|
||||||
|
|
|
||||||
46
kernel/fs.h
46
kernel/fs.h
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
146
kernel/proc.h
146
kernel/proc.h
|
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
328
kernel/riscv.h
328
kernel/riscv.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
52
user/user.h
52
user/user.h
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue