1 /*
2 * Copyright (c) 2010 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/err.h>
9 #include <lk/debug.h>
10 #include <lk/trace.h>
11 #include <platform.h>
12 #include "platform_p.h"
13 #include <platform/armemu.h>
14 #include <lib/bio.h>
15 #include <lk/reg.h>
16
get_blkdev_len(void)17 static uint64_t get_blkdev_len(void) {
18 return *REG64(BDEV_LEN);
19 }
20
read_block(struct bdev * dev,void * buf,bnum_t block,uint count)21 ssize_t read_block(struct bdev *dev, void *buf, bnum_t block, uint count) {
22 /* assume args have been validated by layer above */
23 *REG32(BDEV_CMD_ADDR) = (uint32_t)buf;
24 *REG64(BDEV_CMD_OFF) = (uint64_t)((uint64_t)block * dev->block_size);
25 *REG32(BDEV_CMD_LEN) = count * dev->block_size;
26
27 *REG32(BDEV_CMD) = BDEV_CMD_READ;
28
29 uint32_t err = *REG32(BDEV_CMD) & BDEV_CMD_ERRMASK;
30 if (err == BDEV_CMD_ERR_NONE)
31 return count * dev->block_size;
32 else
33 return ERR_IO;
34 }
35
write_block(struct bdev * dev,const void * buf,bnum_t block,uint count)36 ssize_t write_block(struct bdev *dev, const void *buf, bnum_t block, uint count) {
37 /* assume args have been validated by layer above */
38 *REG32(BDEV_CMD_ADDR) = (uint32_t)buf;
39 *REG64(BDEV_CMD_OFF) = (uint64_t)((uint64_t)block * dev->block_size);
40 *REG32(BDEV_CMD_LEN) = count * dev->block_size;
41
42 *REG32(BDEV_CMD) = BDEV_CMD_WRITE;
43
44 uint32_t err = *REG32(BDEV_CMD) & BDEV_CMD_ERRMASK;
45 if (err == BDEV_CMD_ERR_NONE)
46 return count * dev->block_size;
47 else
48 return ERR_IO;
49 }
50
platform_init_blkdev(void)51 void platform_init_blkdev(void) {
52 static bdev_t dev;
53
54 if ((*REG32(SYSINFO_FEATURES) & SYSINFO_FEATURE_BLOCKDEV) == 0)
55 return; // no block device
56
57 TRACEF("device len %lld\n", get_blkdev_len());
58
59 if (get_blkdev_len() == 0)
60 return;
61
62 bio_initialize_bdev(&dev, "block0", 512, get_blkdev_len() / 512, 0, NULL,
63 BIO_FLAGS_NONE);
64
65 // fill in hooks
66 dev.read_block = &read_block;
67 dev.write_block = &write_block;
68
69 bio_register_device(&dev);
70 }
71
72