Skip to content

Commit

Permalink
microkit abstracted out from uiolib
Browse files Browse the repository at this point in the history
  • Loading branch information
erichchan999 committed Feb 1, 2024
1 parent eb0016a commit ed3a98b
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 114 deletions.
9 changes: 8 additions & 1 deletion examples/virtio/blk_driver_vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ static void register_passthrough_irq(int irq, microkit_channel irq_ch) {
#define UIO_BLK_IRQ 50
#define VSWITCH_BLK 3

uintptr_t uio_irq;

void uio_ack(size_t vcpu_id, int irq, void *cookie) {
LOG_VMM("uio_ack!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
microkit_irq_ack(VSWITCH_BLK);
}

/* Virtio Console */
#define SERIAL_MUX_TX_CH 1
#define SERIAL_MUX_RX_CH 2
Expand Down Expand Up @@ -169,7 +176,7 @@ void init(void) {
assert(success);

/* Register UIO irq */
virq_register(GUEST_VCPU_ID, UIO_BLK_IRQ, &dummy_ack, NULL);
virq_register(GUEST_VCPU_ID, UIO_BLK_IRQ, &uio_ack, NULL);

/* Finally start the guest */
guest_start(GUEST_VCPU_ID, kernel_pc, GUEST_DTB_VADDR, GUEST_INIT_RAM_DISK_VADDR);
Expand Down
109 changes: 53 additions & 56 deletions examples/virtio/board/qemu_arm_virt/blk_driver_vm/userlevel/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,77 +15,74 @@
#include "libuio.h"
#include "block.h"

/* Uncomment this to enable debug logging */
#define DEBUG_UIO_BLOCK

#if defined(DEBUG_UIO_BLOCK)
#define LOG_UIO_BLOCK(...) do{ printf("UIO_DRIVER(BLOCK): "); printf(__VA_ARGS__); }while(0)
#else
#define LOG_UIO_BLOCK(...) do{}while(0)
#endif

#define LOG_UIO_BLOCK_ERR(...) do{ printf("UIO_DRIVER(BLOCK)|ERROR: "); printf(__VA_ARGS__); }while(0)

#define BLK_CH 3

blk_queue_handle_t h;
uintptr_t blk_data;
blk_storage_info_t *blk_config;

/* as much as we don't want to expose the UIO interface to the guest driver,
* over engineering is still not a good idea. For not I think the guest driver
* should be aware of the Linux UIO interface
*/
void init(int fd)
int driver_init(void **maps, int num_maps)
{
blk_req_queue_t *req_queue;
if ((req_queue = mmap(NULL, 0x200000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) -1) {
printf("req_queue: mmap failed, errno: %d\n", errno);
close(fd);
exit(1);
}

blk_resp_queue_t *resp_queue;
if ((resp_queue = mmap(NULL, 0x200000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 1 * getpagesize())) == (void *) -1) {
printf("resp_queue: mmap failed, errno: %d\n", errno);
close(fd);
exit(2);
}

void *data;
if ((data = mmap(NULL, 0x200000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 2 * getpagesize())) == (void *) -1) {
printf("blk_data: mmap failed, errno: %d\n", errno);
close(fd);
exit(3);
}
blk_data = (uintptr_t)data;

if ((blk_config = mmap(NULL, 0x200000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 3 * getpagesize())) == (void *) -1) {
printf("blk_config: mmap failed, errno: %d\n", errno);
close(fd);
exit(4);
if (num_maps != 4) {
LOG_UIO_BLOCK_ERR("Expecting 4 maps, got %d\n", num_maps);
return -1;
}

blk_req_queue_t *req_queue = (blk_req_queue_t *)maps[0];
blk_resp_queue_t *resp_queue = (blk_resp_queue_t *)maps[1];
blk_data = (uintptr_t)maps[2];
blk_config = (blk_storage_info_t *)maps[3];

blk_queue_init(&h, req_queue, resp_queue, false, BLK_REQ_QUEUE_SIZE, BLK_RESP_QUEUE_SIZE);

// @TODO, @ericc: Query the block device we have and fill in the blk_config
// just random numbers I've chosen for now
blk_config->blocksize = 1024;
blk_config->size = 1024 * 1024 * 1024;
blk_config->read_only = false;
blk_config->ready = true;

// Notify the other side that driver is ready
uio_notify();

return 0;
}

void notified(microkit_channel ch)
void driver_notified()
{
if (ch == BLK_CH) {
printf("Received notification on channel %d\n", ch);
blk_request_code_t ret_code;
uintptr_t ret_addr;
uint32_t ret_sector;
uint16_t ret_count;
uint32_t ret_id;

blk_request_code_t ret_code;
uintptr_t ret_addr;
uint32_t ret_sector;
uint16_t ret_count;
uint32_t ret_id;
while (!blk_req_queue_empty(&h)) {
blk_dequeue_req(&h, &ret_code, &ret_addr, &ret_sector, &ret_count, &ret_id);
printf("Received command: code=%d, addr=%p, sector=%d, count=%d, id=%d\n", ret_code, (void *)ret_addr, ret_sector, ret_count, ret_id);

while (!blk_req_queue_empty(&h)) {
blk_dequeue_req(&h, &ret_code, &ret_addr, &ret_sector, &ret_count, &ret_id);
printf("Received command: code=%d, addr=%p, sector=%d, count=%d, id=%d\n", ret_code, (void *)ret_addr, ret_sector, ret_count, ret_id);

blk_response_status_t status = SUCCESS;
uintptr_t addr = ret_addr;
uint16_t count = ret_count;
uint16_t success_count = ret_count;
uint32_t id = ret_id;
//@ericc: what happens if this response is dropped? should we have a timeout in client?
if (blk_resp_queue_full(&h)) {
printf("Response ring is full, dropping response\n");
continue;
}
blk_enqueue_resp(&h, status, addr, count, success_count, id);
blk_response_status_t status = SUCCESS;
uintptr_t addr = ret_addr;
uint16_t count = ret_count;
uint16_t success_count = ret_count;
uint32_t id = ret_id;
//@ericc: what happens if this response is dropped? should we have a timeout in client?
if (blk_resp_queue_full(&h)) {
printf("Response ring is full, dropping response\n");
continue;
}

microkit_notify(BLK_CH);
blk_enqueue_resp(&h, status, addr, count, success_count, id);
}

uio_notify();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
* Copyright 2023, UNSW
* Copyright 2024, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once

void init(int fd);
void notified(microkit_channel ch);
int driver_init(void **maps, int num_maps);
void driver_notified();
Loading

0 comments on commit ed3a98b

Please sign in to comment.