move most of virtio-blk example outside main
This commit is contained in:
parent
a798d37ebe
commit
164f56ca57
3 changed files with 125 additions and 94 deletions
1
Makefile
1
Makefile
|
|
@ -65,6 +65,7 @@ KERNEL_SOURCES := \
|
|||
src/tlsf.c \
|
||||
src/virtio-common.c \
|
||||
src/virtio-block.c \
|
||||
src/virtio-block-example.c \
|
||||
$(KERNEL_SOURCES_$(ARCH)) \
|
||||
# end of kernel sources list
|
||||
|
||||
|
|
|
|||
105
src/kernel.c
105
src/kernel.c
|
|
@ -65,72 +65,6 @@ void _start() {
|
|||
}
|
||||
}
|
||||
|
||||
void mycb(struct blk_req req, void* userdata) {
|
||||
char *type = NULL;
|
||||
switch (req.type) {
|
||||
case BLK_REQ_READ: type = "READ"; break;
|
||||
case BLK_REQ_WRITE: type = "WRITE"; break;
|
||||
case BLK_REQ_FLUSH: type = "FLUSH"; break;
|
||||
}
|
||||
if (req.type == BLK_REQ_FLUSH) {
|
||||
printlinef("%s done.", type);
|
||||
} else {
|
||||
uint8_t *p = pa_to_pointer(req.data);
|
||||
printlinef("%s done: %u sectors starting at %u", type, req.num_sectors, req.sector);
|
||||
for (int i = 0; i < req.num_sectors; i++) {
|
||||
printlinef("sector %u: %X8 %X8 %X8 %X8 ...", req.sector + i,
|
||||
p[512*i], p[512*i + 1], p[512*i + 2], p[512*i + 3]
|
||||
);
|
||||
}
|
||||
}
|
||||
slab_cache_free(pa_to_pointer(req.data));
|
||||
}
|
||||
|
||||
struct slab_cache sector_cache;
|
||||
struct cache_entry {
|
||||
bool used;
|
||||
bool done;
|
||||
uint64_t bno;
|
||||
struct pa data;
|
||||
} re1, re2;
|
||||
|
||||
void get_block_done(struct blk_req req, void* userdata) {
|
||||
struct cache_entry *entry = userdata;
|
||||
entry->done = true;
|
||||
}
|
||||
uint8_t *get_block(uint64_t bno,void *cbdata) {
|
||||
struct virtio_blk_context *ctx = cbdata;
|
||||
struct pa data = pa_from_pointer(slab_cache_alloc(§or_cache));
|
||||
volatile struct cache_entry *entry;
|
||||
if (!re1.used) {
|
||||
entry = &re1;
|
||||
} else {
|
||||
ASSERT(!re2.used);
|
||||
entry = &re2;
|
||||
}
|
||||
entry->used = true;
|
||||
entry->done = false;
|
||||
entry->bno = bno;
|
||||
entry->data = data;
|
||||
virtio_blk_queue_req(ctx, BLK_READ(bno, 1, data), get_block_done, entry);
|
||||
|
||||
while (!entry->done) {
|
||||
virtio_blk_on_used_notif(ctx);
|
||||
}
|
||||
return pa_to_pointer(entry->data);
|
||||
}
|
||||
void put_block(uint64_t bno, void *cbdata) {
|
||||
struct cache_entry *entry;
|
||||
if (re1.used && re1.bno == bno) {
|
||||
entry = &re1;
|
||||
} else {
|
||||
ASSERT(re2.used && re2.bno == bno);
|
||||
entry = &re2;
|
||||
}
|
||||
slab_cache_free(pa_to_pointer(entry->data));
|
||||
entry->used = false;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
__asm__("sti");
|
||||
|
||||
|
|
@ -143,36 +77,19 @@ void main(void) {
|
|||
app_init_global();
|
||||
printline("KarlOS initialized");
|
||||
|
||||
// extern struct app_template cursor_template;
|
||||
// app_push(&cursor_template, &tex, &RECT_XYWH(10, 10, 500, 500));
|
||||
// extern struct app_template snake_template;
|
||||
// app_push(&snake_template, NULL, &RECT_XYWH(10, 10, 500, 500));
|
||||
|
||||
__asm__ ("sti");
|
||||
struct virtio_dev_iter iter;
|
||||
virtio_dev_iter_init(&iter, VIRTIO_DEV_KIND_BLOCK);
|
||||
struct bdf bdf;
|
||||
if (virtio_dev_iter_next(&iter, &bdf)) {
|
||||
printlinef("found virtio block device with bdf %X8", bdf);
|
||||
struct bdf second_bdf;
|
||||
if (virtio_dev_iter_next(&iter, &second_bdf)) {
|
||||
printline("WARNING: more than one virtio block device, ignoring all but first");
|
||||
}
|
||||
struct virtio_blk_context ctx;
|
||||
virtio_blk_device_init(bdf, &ctx);
|
||||
|
||||
slab_cache_init_with_align(§or_cache, 512, 512, NULL, NULL);
|
||||
|
||||
uint64_t size;
|
||||
uint64_t bno;
|
||||
ASSERT(tar_get_file_info_custom("b.txt", ctx.num_sectors, get_block, put_block, &ctx,
|
||||
&size, &bno));
|
||||
ASSERT(!re1.used && !re2.used);
|
||||
printlinef("found file: size %lu bno %lu", size, bno);
|
||||
|
||||
slab_cache_destroy(§or_cache);
|
||||
} else {
|
||||
printline("WARNING: did not find virtio device.");
|
||||
bool vbe_initialize();
|
||||
bool vbe_read_file_info_from_disk(const char *name, uint64_t *size, uint64_t *bno);
|
||||
bool success = vbe_initialize();
|
||||
if (success) {
|
||||
uint64_t size, bno;
|
||||
const char *name = "a.txt";
|
||||
ASSERT(vbe_read_file_info_from_disk(name, &size, &bno));
|
||||
printlinef("file %s: size %u bno %u", name, size, bno);
|
||||
name = "b.txt";
|
||||
ASSERT(vbe_read_file_info_from_disk(name, &size, &bno));
|
||||
printlinef("file %s: size %u bno %u", name, size, bno);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
|
|
|||
113
src/virtio-block-example.c
Normal file
113
src/virtio-block-example.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include "virtio-block.h"
|
||||
#include "std.h"
|
||||
#include "slab.h"
|
||||
#include "tar.h"
|
||||
|
||||
void mycb(struct blk_req req, void* userdata) {
|
||||
char *type = NULL;
|
||||
switch (req.type) {
|
||||
case BLK_REQ_READ: type = "READ"; break;
|
||||
case BLK_REQ_WRITE: type = "WRITE"; break;
|
||||
case BLK_REQ_FLUSH: type = "FLUSH"; break;
|
||||
}
|
||||
if (req.type == BLK_REQ_FLUSH) {
|
||||
printlinef("%s done.", type);
|
||||
} else {
|
||||
uint8_t *p = pa_to_pointer(req.data);
|
||||
printlinef("%s done: %u sectors starting at %u", type, req.num_sectors, req.sector);
|
||||
for (int i = 0; i < req.num_sectors; i++) {
|
||||
printlinef("sector %u: %X8 %X8 %X8 %X8 ...", req.sector + i,
|
||||
p[512*i], p[512*i + 1], p[512*i + 2], p[512*i + 3]
|
||||
);
|
||||
}
|
||||
}
|
||||
slab_cache_free(pa_to_pointer(req.data));
|
||||
}
|
||||
|
||||
struct slab_cache sector_cache;
|
||||
struct cache_entry {
|
||||
bool used;
|
||||
bool done;
|
||||
uint64_t bno;
|
||||
struct pa data;
|
||||
} re1, re2;
|
||||
|
||||
void get_block_done(struct blk_req req, void* userdata) {
|
||||
struct cache_entry *entry = userdata;
|
||||
entry->done = true;
|
||||
}
|
||||
uint8_t *get_block(uint64_t bno,void *cbdata) {
|
||||
struct virtio_blk_context *ctx = cbdata;
|
||||
struct pa data = pa_from_pointer(slab_cache_alloc(§or_cache));
|
||||
volatile struct cache_entry *entry;
|
||||
if (!re1.used) {
|
||||
entry = &re1;
|
||||
} else {
|
||||
ASSERT(!re2.used);
|
||||
entry = &re2;
|
||||
}
|
||||
entry->used = true;
|
||||
entry->done = false;
|
||||
entry->bno = bno;
|
||||
entry->data = data;
|
||||
virtio_blk_queue_req(ctx, BLK_READ(bno, 1, data), get_block_done, entry);
|
||||
|
||||
while (!entry->done) {
|
||||
virtio_blk_on_used_notif(ctx);
|
||||
}
|
||||
return pa_to_pointer(entry->data);
|
||||
}
|
||||
void put_block(uint64_t bno, void *cbdata) {
|
||||
struct cache_entry *entry;
|
||||
if (re1.used && re1.bno == bno) {
|
||||
entry = &re1;
|
||||
} else {
|
||||
ASSERT(re2.used && re2.bno == bno);
|
||||
entry = &re2;
|
||||
}
|
||||
slab_cache_free(pa_to_pointer(entry->data));
|
||||
entry->used = false;
|
||||
}
|
||||
|
||||
bool vbe_initialized = false;
|
||||
bool vbe_initialized_successful = false;
|
||||
struct virtio_blk_context vbe_ctx;
|
||||
|
||||
bool vbe_initialize() {
|
||||
slab_cache_init_with_align(§or_cache, 512, 512, NULL, NULL);
|
||||
struct virtio_dev_iter iter;
|
||||
virtio_dev_iter_init(&iter, VIRTIO_DEV_KIND_BLOCK);
|
||||
struct bdf bdf;
|
||||
if (virtio_dev_iter_next(&iter, &bdf)) {
|
||||
printlinef("found virtio block device with bdf %X8", bdf);
|
||||
struct bdf second_bdf;
|
||||
if (virtio_dev_iter_next(&iter, &second_bdf)) {
|
||||
printline("WARNING: more than one virtio block device, ignoring all but first");
|
||||
}
|
||||
virtio_blk_device_init(bdf, &vbe_ctx);
|
||||
vbe_initialized = true;
|
||||
vbe_initialized_successful = true;
|
||||
return true;
|
||||
} else {
|
||||
printline("WARNING: did not find virtio device.");
|
||||
vbe_initialized = true;
|
||||
vbe_initialized_successful = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool vbe_read_file_info_from_disk(const char *name, uint64_t *size, uint64_t *bno) {
|
||||
ASSERT(vbe_initialized && vbe_initialized_successful);
|
||||
if (!vbe_initialized) {
|
||||
bool success = vbe_initialize();
|
||||
vbe_initialized = true;
|
||||
vbe_initialized_successful = success;
|
||||
}
|
||||
if (!vbe_initialized_successful) {
|
||||
return false;
|
||||
}
|
||||
ASSERT(tar_get_file_info_custom(name, vbe_ctx.num_sectors, get_block, put_block, &vbe_ctx,
|
||||
size, bno));
|
||||
ASSERT(!re1.used && !re2.used);
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue