update name of code to labcodes

This commit is contained in:
chyyuu
2013-09-17 22:21:48 +08:00
parent 759eca9dda
commit 3f8d5876b9
726 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
#include <defs.h>
#include <string.h>
#include <stat.h>
#include <dev.h>
#include <inode.h>
#include <unistd.h>
#include <error.h>
/*
* dev_open - Called for each open().
*/
static int
dev_open(struct inode *node, uint32_t open_flags) {
if (open_flags & (O_CREAT | O_TRUNC | O_EXCL | O_APPEND)) {
return -E_INVAL;
}
struct device *dev = vop_info(node, device);
return dop_open(dev, open_flags);
}
/*
* dev_close - Called on the last close(). Just pass through.
*/
static int
dev_close(struct inode *node) {
struct device *dev = vop_info(node, device);
return dop_close(dev);
}
/*
* dev_read -Called for read. Hand off to iobuf.
*/
static int
dev_read(struct inode *node, struct iobuf *iob) {
struct device *dev = vop_info(node, device);
return dop_io(dev, iob, 0);
}
/*
* dev_write -Called for write. Hand off to iobuf.
*/
static int
dev_write(struct inode *node, struct iobuf *iob) {
struct device *dev = vop_info(node, device);
return dop_io(dev, iob, 1);
}
/*
* dev_ioctl - Called for ioctl(). Just pass through.
*/
static int
dev_ioctl(struct inode *node, int op, void *data) {
struct device *dev = vop_info(node, device);
return dop_ioctl(dev, op, data);
}
/*
* dev_fstat - Called for stat().
* Set the type and the size (block devices only).
* The link count for a device is always 1.
*/
static int
dev_fstat(struct inode *node, struct stat *stat) {
int ret;
memset(stat, 0, sizeof(struct stat));
if ((ret = vop_gettype(node, &(stat->st_mode))) != 0) {
return ret;
}
struct device *dev = vop_info(node, device);
stat->st_nlinks = 1;
stat->st_blocks = dev->d_blocks;
stat->st_size = stat->st_blocks * dev->d_blocksize;
return 0;
}
/*
* dev_gettype - Return the type. A device is a "block device" if it has a known
* length. A device that generates data in a stream is a "character
* device".
*/
static int
dev_gettype(struct inode *node, uint32_t *type_store) {
struct device *dev = vop_info(node, device);
*type_store = (dev->d_blocks > 0) ? S_IFBLK : S_IFCHR;
return 0;
}
/*
* dev_tryseek - Attempt a seek.
* For block devices, require block alignment.
* For character devices, prohibit seeking entirely.
*/
static int
dev_tryseek(struct inode *node, off_t pos) {
struct device *dev = vop_info(node, device);
if (dev->d_blocks > 0) {
if ((pos % dev->d_blocksize) == 0) {
if (pos >= 0 && pos < dev->d_blocks * dev->d_blocksize) {
return 0;
}
}
}
return -E_INVAL;
}
/*
* dev_lookup - Name lookup.
*
* One interesting feature of device:name pathname syntax is that you
* can implement pathnames on arbitrary devices. For instance, if you
* had a graphics device that supported multiple resolutions (which we
* don't), you might arrange things so that you could open it with
* pathnames like "video:800x600/24bpp" in order to select the operating
* mode.
*
* However, we have no support for this in the base system.
*/
static int
dev_lookup(struct inode *node, char *path, struct inode **node_store) {
if (*path != '\0') {
return -E_NOENT;
}
vop_ref_inc(node);
*node_store = node;
return 0;
}
/*
* Function table for device inodes.
*/
static const struct inode_ops dev_node_ops = {
.vop_magic = VOP_MAGIC,
.vop_open = dev_open,
.vop_close = dev_close,
.vop_read = dev_read,
.vop_write = dev_write,
.vop_fstat = dev_fstat,
.vop_ioctl = dev_ioctl,
.vop_gettype = dev_gettype,
.vop_tryseek = dev_tryseek,
.vop_lookup = dev_lookup,
};
#define init_device(x) \
do { \
extern void dev_init_##x(void); \
dev_init_##x(); \
} while (0)
/* dev_init - Initialization functions for builtin vfs-level devices. */
void
dev_init(void) {
// init_device(null);
init_device(stdin);
init_device(stdout);
init_device(disk0);
}
/* dev_create_inode - Create inode for a vfs-level device. */
struct inode *
dev_create_inode(void) {
struct inode *node;
if ((node = alloc_inode(device)) != NULL) {
vop_init(node, &dev_node_ops, NULL);
}
return node;
}

View File

@@ -0,0 +1,31 @@
#ifndef __KERN_FS_DEVS_DEV_H__
#define __KERN_FS_DEVS_DEV_H__
#include <defs.h>
struct inode;
struct iobuf;
/*
* Filesystem-namespace-accessible device.
* d_io is for both reads and writes; the iobuf will indicates the direction.
*/
struct device {
size_t d_blocks;
size_t d_blocksize;
int (*d_open)(struct device *dev, uint32_t open_flags);
int (*d_close)(struct device *dev);
int (*d_io)(struct device *dev, struct iobuf *iob, bool write);
int (*d_ioctl)(struct device *dev, int op, void *data);
};
#define dop_open(dev, open_flags) ((dev)->d_open(dev, open_flags))
#define dop_close(dev) ((dev)->d_close(dev))
#define dop_io(dev, iob, write) ((dev)->d_io(dev, iob, write))
#define dop_ioctl(dev, op, data) ((dev)->d_ioctl(dev, op, data))
void dev_init(void);
struct inode *dev_create_inode(void);
#endif /* !__KERN_FS_DEVS_DEV_H__ */

View File

@@ -0,0 +1,144 @@
#include <defs.h>
#include <mmu.h>
#include <sem.h>
#include <ide.h>
#include <inode.h>
#include <kmalloc.h>
#include <dev.h>
#include <vfs.h>
#include <iobuf.h>
#include <error.h>
#include <assert.h>
#define DISK0_BLKSIZE PGSIZE
#define DISK0_BUFSIZE (4 * DISK0_BLKSIZE)
#define DISK0_BLK_NSECT (DISK0_BLKSIZE / SECTSIZE)
static char *disk0_buffer;
static semaphore_t disk0_sem;
static void
lock_disk0(void) {
down(&(disk0_sem));
}
static void
unlock_disk0(void) {
up(&(disk0_sem));
}
static int
disk0_open(struct device *dev, uint32_t open_flags) {
return 0;
}
static int
disk0_close(struct device *dev) {
return 0;
}
static void
disk0_read_blks_nolock(uint32_t blkno, uint32_t nblks) {
int ret;
uint32_t sectno = blkno * DISK0_BLK_NSECT, nsecs = nblks * DISK0_BLK_NSECT;
if ((ret = ide_read_secs(DISK0_DEV_NO, sectno, disk0_buffer, nsecs)) != 0) {
panic("disk0: read blkno = %d (sectno = %d), nblks = %d (nsecs = %d): 0x%08x.\n",
blkno, sectno, nblks, nsecs, ret);
}
}
static void
disk0_write_blks_nolock(uint32_t blkno, uint32_t nblks) {
int ret;
uint32_t sectno = blkno * DISK0_BLK_NSECT, nsecs = nblks * DISK0_BLK_NSECT;
if ((ret = ide_write_secs(DISK0_DEV_NO, sectno, disk0_buffer, nsecs)) != 0) {
panic("disk0: write blkno = %d (sectno = %d), nblks = %d (nsecs = %d): 0x%08x.\n",
blkno, sectno, nblks, nsecs, ret);
}
}
static int
disk0_io(struct device *dev, struct iobuf *iob, bool write) {
off_t offset = iob->io_offset;
size_t resid = iob->io_resid;
uint32_t blkno = offset / DISK0_BLKSIZE;
uint32_t nblks = resid / DISK0_BLKSIZE;
/* don't allow I/O that isn't block-aligned */
if ((offset % DISK0_BLKSIZE) != 0 || (resid % DISK0_BLKSIZE) != 0) {
return -E_INVAL;
}
/* don't allow I/O past the end of disk0 */
if (blkno + nblks > dev->d_blocks) {
return -E_INVAL;
}
/* read/write nothing ? */
if (nblks == 0) {
return 0;
}
lock_disk0();
while (resid != 0) {
size_t copied, alen = DISK0_BUFSIZE;
if (write) {
iobuf_move(iob, disk0_buffer, alen, 0, &copied);
assert(copied != 0 && copied <= resid && copied % DISK0_BLKSIZE == 0);
nblks = copied / DISK0_BLKSIZE;
disk0_write_blks_nolock(blkno, nblks);
}
else {
if (alen > resid) {
alen = resid;
}
nblks = alen / DISK0_BLKSIZE;
disk0_read_blks_nolock(blkno, nblks);
iobuf_move(iob, disk0_buffer, alen, 1, &copied);
assert(copied == alen && copied % DISK0_BLKSIZE == 0);
}
resid -= copied, blkno += nblks;
}
unlock_disk0();
return 0;
}
static int
disk0_ioctl(struct device *dev, int op, void *data) {
return -E_UNIMP;
}
static void
disk0_device_init(struct device *dev) {
static_assert(DISK0_BLKSIZE % SECTSIZE == 0);
if (!ide_device_valid(DISK0_DEV_NO)) {
panic("disk0 device isn't available.\n");
}
dev->d_blocks = ide_device_size(DISK0_DEV_NO) / DISK0_BLK_NSECT;
dev->d_blocksize = DISK0_BLKSIZE;
dev->d_open = disk0_open;
dev->d_close = disk0_close;
dev->d_io = disk0_io;
dev->d_ioctl = disk0_ioctl;
sem_init(&(disk0_sem), 1);
static_assert(DISK0_BUFSIZE % DISK0_BLKSIZE == 0);
if ((disk0_buffer = kmalloc(DISK0_BUFSIZE)) == NULL) {
panic("disk0 alloc buffer failed.\n");
}
}
void
dev_init_disk0(void) {
struct inode *node;
if ((node = dev_create_inode()) == NULL) {
panic("disk0: dev_create_node.\n");
}
disk0_device_init(vop_info(node, device));
int ret;
if ((ret = vfs_add_dev("disk0", node, 1)) != 0) {
panic("disk0: vfs_add_dev: %e.\n", ret);
}
}

View File

@@ -0,0 +1,126 @@
#include <defs.h>
#include <stdio.h>
#include <wait.h>
#include <sync.h>
#include <proc.h>
#include <sched.h>
#include <dev.h>
#include <vfs.h>
#include <iobuf.h>
#include <inode.h>
#include <unistd.h>
#include <error.h>
#include <assert.h>
#define STDIN_BUFSIZE 4096
static char stdin_buffer[STDIN_BUFSIZE];
static off_t p_rpos, p_wpos;
static wait_queue_t __wait_queue, *wait_queue = &__wait_queue;
void
dev_stdin_write(char c) {
bool intr_flag;
if (c != '\0') {
local_intr_save(intr_flag);
{
stdin_buffer[p_wpos % STDIN_BUFSIZE] = c;
if (p_wpos - p_rpos < STDIN_BUFSIZE) {
p_wpos ++;
}
if (!wait_queue_empty(wait_queue)) {
wakeup_queue(wait_queue, WT_KBD, 1);
}
}
local_intr_restore(intr_flag);
}
}
static int
dev_stdin_read(char *buf, size_t len) {
int ret = 0;
bool intr_flag;
local_intr_save(intr_flag);
{
for (; ret < len; ret ++, p_rpos ++) {
try_again:
if (p_rpos < p_wpos) {
*buf ++ = stdin_buffer[p_rpos % STDIN_BUFSIZE];
}
else {
wait_t __wait, *wait = &__wait;
wait_current_set(wait_queue, wait, WT_KBD);
local_intr_restore(intr_flag);
schedule();
local_intr_save(intr_flag);
wait_current_del(wait_queue, wait);
if (wait->wakeup_flags == WT_KBD) {
goto try_again;
}
break;
}
}
}
local_intr_restore(intr_flag);
return ret;
}
static int
stdin_open(struct device *dev, uint32_t open_flags) {
if (open_flags != O_RDONLY) {
return -E_INVAL;
}
return 0;
}
static int
stdin_close(struct device *dev) {
return 0;
}
static int
stdin_io(struct device *dev, struct iobuf *iob, bool write) {
if (!write) {
int ret;
if ((ret = dev_stdin_read(iob->io_base, iob->io_resid)) > 0) {
iob->io_resid -= ret;
}
return ret;
}
return -E_INVAL;
}
static int
stdin_ioctl(struct device *dev, int op, void *data) {
return -E_INVAL;
}
static void
stdin_device_init(struct device *dev) {
dev->d_blocks = 0;
dev->d_blocksize = 1;
dev->d_open = stdin_open;
dev->d_close = stdin_close;
dev->d_io = stdin_io;
dev->d_ioctl = stdin_ioctl;
p_rpos = p_wpos = 0;
wait_queue_init(wait_queue);
}
void
dev_init_stdin(void) {
struct inode *node;
if ((node = dev_create_inode()) == NULL) {
panic("stdin: dev_create_node.\n");
}
stdin_device_init(vop_info(node, device));
int ret;
if ((ret = vfs_add_dev("stdin", node, 0)) != 0) {
panic("stdin: vfs_add_dev: %e.\n", ret);
}
}

View File

@@ -0,0 +1,64 @@
#include <defs.h>
#include <stdio.h>
#include <dev.h>
#include <vfs.h>
#include <iobuf.h>
#include <inode.h>
#include <unistd.h>
#include <error.h>
#include <assert.h>
static int
stdout_open(struct device *dev, uint32_t open_flags) {
if (open_flags != O_WRONLY) {
return -E_INVAL;
}
return 0;
}
static int
stdout_close(struct device *dev) {
return 0;
}
static int
stdout_io(struct device *dev, struct iobuf *iob, bool write) {
if (write) {
char *data = iob->io_base;
for (; iob->io_resid != 0; iob->io_resid --) {
cputchar(*data ++);
}
return 0;
}
return -E_INVAL;
}
static int
stdout_ioctl(struct device *dev, int op, void *data) {
return -E_INVAL;
}
static void
stdout_device_init(struct device *dev) {
dev->d_blocks = 0;
dev->d_blocksize = 1;
dev->d_open = stdout_open;
dev->d_close = stdout_close;
dev->d_io = stdout_io;
dev->d_ioctl = stdout_ioctl;
}
void
dev_init_stdout(void) {
struct inode *node;
if ((node = dev_create_inode()) == NULL) {
panic("stdout: dev_create_node.\n");
}
stdout_device_init(vop_info(node, device));
int ret;
if ((ret = vfs_add_dev("stdout", node, 0)) != 0) {
panic("stdout: vfs_add_dev: %e.\n", ret);
}
}