blob: b5fbc4364f7979d72fb26a07f7efd8bc2d3ada28 [file] [log] [blame]
Travis Geiselbrecht96f6dfe2010-05-06 17:21:08 -07001/*
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
31static bdev_t dev;
32
33static uint64_t get_blkdev_len(void)
34{
35 return *REG64(BDEV_LEN);
36}
37
38ssize_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
54ssize_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
70void 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