First version
[3rdparty/ote_partner/tlk.git] / platform / armemu / blkdev.c
1 /*
2  * Copyright (c) 2010 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <err.h>
24 #include <debug.h>
25 #include <platform.h>
26 #include "platform_p.h"
27 #include <platform/armemu.h>
28 #include <lib/bio.h>
29 #include <reg.h>
30
31 static bdev_t dev;
32
33 static uint64_t get_blkdev_len(void)
34 {
35         return *REG64(BDEV_LEN);
36 }
37
38 ssize_t read_block(struct bdev *dev, void *buf, bnum_t block, uint count)
39 {
40         /* assume args have been validated by layer above */
41         *REG32(BDEV_CMD_ADDR) = (uint32_t)buf;
42         *REG64(BDEV_CMD_OFF) = (uint64_t)((uint64_t)block * dev->block_size);
43         *REG32(BDEV_CMD_LEN) = count * dev->block_size;
44
45         *REG32(BDEV_CMD) = BDEV_CMD_READ;
46
47         uint32_t err = *REG32(BDEV_CMD) & BDEV_CMD_ERRMASK;
48         if (err == BDEV_CMD_ERR_NONE)
49                 return count * dev->block_size;
50         else
51                 return ERR_IO;
52 }
53
54 ssize_t write_block(struct bdev *dev, const void *buf, bnum_t block, uint count)
55 {
56         /* assume args have been validated by layer above */
57         *REG32(BDEV_CMD_ADDR) = (uint32_t)buf;
58         *REG64(BDEV_CMD_OFF) = (uint64_t)((uint64_t)block * dev->block_size);
59         *REG32(BDEV_CMD_LEN) = count * dev->block_size;
60
61         *REG32(BDEV_CMD) = BDEV_CMD_WRITE;
62
63         uint32_t err = *REG32(BDEV_CMD) & BDEV_CMD_ERRMASK;
64         if (err == BDEV_CMD_ERR_NONE)
65                 return count * dev->block_size;
66         else
67                 return ERR_IO;
68 }
69
70 void platform_init_blkdev(void)
71 {
72         if ((*REG32(SYSINFO_FEATURES) & SYSINFO_FEATURE_BLOCKDEV) == 0)
73                 return; // no block device
74
75         TRACEF("device len %lld\n", get_blkdev_len());
76
77         if (get_blkdev_len() == 0)
78                 return;
79
80         bio_initialize_bdev(&dev, "block0", 512, get_blkdev_len() / 512);
81
82         // fill in hooks
83         dev.read_block = &read_block;
84         dev.write_block = &write_block;
85
86         bio_register_device(&dev);
87 }
88