mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-13 20:36:02 +01:00
This commit is contained in:
commit
c4408291bf
@ -56,6 +56,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
|||||||
imply DM_SCSI
|
imply DM_SCSI
|
||||||
imply SYS_NS16550
|
imply SYS_NS16550
|
||||||
imply SIFIVE_SERIAL
|
imply SIFIVE_SERIAL
|
||||||
|
imply HTIF_CONSOLE if 64BIT
|
||||||
imply SYSRESET
|
imply SYSRESET
|
||||||
imply SYSRESET_CMD_POWEROFF
|
imply SYSRESET_CMD_POWEROFF
|
||||||
imply SYSRESET_SYSCON
|
imply SYSRESET_SYSCON
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <dm/ofnode.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
@ -16,6 +17,17 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_MTD_NOR_FLASH)
|
||||||
|
int is_flash_available(void)
|
||||||
|
{
|
||||||
|
if (!ofnode_equal(ofnode_by_compatible(ofnode_null(), "cfi-flash"),
|
||||||
|
ofnode_null()))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int board_init(void)
|
int board_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -4,19 +4,24 @@
|
|||||||
QEMU RISC-V
|
QEMU RISC-V
|
||||||
===========
|
===========
|
||||||
|
|
||||||
QEMU for RISC-V supports a special 'virt' machine designed for emulation and
|
QEMU for RISC-V supports a special 'virt' machine and 'spike' machine designed
|
||||||
virtualization purposes. This document describes how to run U-Boot under it.
|
for emulation and virtualization purposes. This document describes how to run
|
||||||
Both 32-bit and 64-bit targets are supported, running in either machine or
|
U-Boot under it. Both 32-bit and 64-bit targets are supported, running in
|
||||||
supervisor mode.
|
either machine or supervisor mode.
|
||||||
|
|
||||||
The QEMU virt machine models a generic RISC-V virtual machine with support for
|
The QEMU virt machine models a generic RISC-V virtual machine with support for
|
||||||
the VirtIO standard networking and block storage devices. It has CLINT, PLIC,
|
the VirtIO standard networking and block storage devices. It has CLINT, PLIC,
|
||||||
16550A UART devices in addition to VirtIO and it also uses device-tree to pass
|
16550A UART devices in addition to VirtIO and it also uses device-tree to pass
|
||||||
configuration information to guest software. It implements RISC-V privileged
|
configuration information to guest software. It implements the latest RISC-V
|
||||||
|
privileged architecture.
|
||||||
|
|
||||||
See :doc:`../../develop/devicetree/dt_qemu` for information on how to see
|
See :doc:`../../develop/devicetree/dt_qemu` for information on how to see
|
||||||
the devicetree actually generated by QEMU.
|
the devicetree actually generated by QEMU.
|
||||||
architecture spec v1.10.
|
|
||||||
|
The QEMU spike machine models a minimalistic RISC-V virtual machine with
|
||||||
|
only CLINT and HTIF devices. It also uses device-tree to pass configuration
|
||||||
|
information to guest software and implements the latest RISC-V privileged
|
||||||
|
architecture.
|
||||||
|
|
||||||
Building U-Boot
|
Building U-Boot
|
||||||
---------------
|
---------------
|
||||||
@ -41,13 +46,17 @@ Running U-Boot
|
|||||||
--------------
|
--------------
|
||||||
The minimal QEMU command line to get U-Boot up and running is:
|
The minimal QEMU command line to get U-Boot up and running is:
|
||||||
|
|
||||||
- For 32-bit RISC-V::
|
- For 32-bit RISC-V virt machine::
|
||||||
|
|
||||||
qemu-system-riscv32 -nographic -machine virt -bios u-boot
|
qemu-system-riscv32 -nographic -machine virt -bios u-boot.bin
|
||||||
|
|
||||||
- For 64-bit RISC-V::
|
- For 64-bit RISC-V virt machine::
|
||||||
|
|
||||||
qemu-system-riscv64 -nographic -machine virt -bios u-boot
|
qemu-system-riscv64 -nographic -machine virt -bios u-boot.bin
|
||||||
|
|
||||||
|
- For 64-bit RISC-V spike machine::
|
||||||
|
|
||||||
|
qemu-system-riscv64 -nographic -machine spike -bios u-boot.bin
|
||||||
|
|
||||||
The commands above create targets with 128MiB memory by default.
|
The commands above create targets with 128MiB memory by default.
|
||||||
A freely configurable amount of RAM can be created via the '-m'
|
A freely configurable amount of RAM can be created via the '-m'
|
||||||
@ -58,6 +67,7 @@ the new setting.
|
|||||||
For instructions on how to run U-Boot in supervisor mode on QEMU
|
For instructions on how to run U-Boot in supervisor mode on QEMU
|
||||||
with OpenSBI, see the documentation available with OpenSBI:
|
with OpenSBI, see the documentation available with OpenSBI:
|
||||||
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
|
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
|
||||||
|
https://github.com/riscv/opensbi/blob/master/docs/platform/spike.md
|
||||||
|
|
||||||
These have been tested in QEMU 5.0.0.
|
These have been tested in QEMU 5.0.0.
|
||||||
|
|
||||||
@ -80,8 +90,9 @@ supported by U-Boot. Clone the OpenSBI repository and run the following command.
|
|||||||
|
|
||||||
See the OpenSBI documentation for full details:
|
See the OpenSBI documentation for full details:
|
||||||
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
|
https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
|
||||||
|
https://github.com/riscv/opensbi/blob/master/docs/platform/spike.md
|
||||||
|
|
||||||
To make the FW_DYNAMIC binary (build/platform/qemu/virt/firmware/fw_dynamic.bin)
|
To make the FW_DYNAMIC binary (build/platform/generic/firmware/fw_dynamic.bin)
|
||||||
available to U-Boot, either copy it into the U-Boot root directory or specify
|
available to U-Boot, either copy it into the U-Boot root directory or specify
|
||||||
its location with the OPENSBI environment variable. Afterwards, compile U-Boot
|
its location with the OPENSBI environment variable. Afterwards, compile U-Boot
|
||||||
with the following commands.
|
with the following commands.
|
||||||
@ -99,17 +110,22 @@ with the following commands.
|
|||||||
The minimal QEMU commands to run U-Boot SPL in both 32-bit and 64-bit
|
The minimal QEMU commands to run U-Boot SPL in both 32-bit and 64-bit
|
||||||
configurations are:
|
configurations are:
|
||||||
|
|
||||||
- For 32-bit RISC-V::
|
- For 32-bit RISC-V virt machine::
|
||||||
|
|
||||||
qemu-system-riscv32 -nographic -machine virt -bios spl/u-boot-spl \
|
qemu-system-riscv32 -nographic -machine virt -bios spl/u-boot-spl.bin \
|
||||||
-device loader,file=u-boot.itb,addr=0x80200000
|
-device loader,file=u-boot.itb,addr=0x80200000
|
||||||
|
|
||||||
- For 64-bit RISC-V::
|
- For 64-bit RISC-V virt machine::
|
||||||
|
|
||||||
qemu-system-riscv64 -nographic -machine virt -bios spl/u-boot-spl \
|
qemu-system-riscv64 -nographic -machine virt -bios spl/u-boot-spl.bin \
|
||||||
-device loader,file=u-boot.itb,addr=0x80200000
|
-device loader,file=u-boot.itb,addr=0x80200000
|
||||||
|
|
||||||
An attached disk can be emulated by adding::
|
- For 64-bit RISC-V spike machine::
|
||||||
|
|
||||||
|
qemu-system-riscv64 -nographic -machine spike -bios spl/u-boot-spl.bin \
|
||||||
|
-device loader,file=u-boot.itb,addr=0x80200000
|
||||||
|
|
||||||
|
An attached disk can be emulated in RISC-V virt machine by adding::
|
||||||
|
|
||||||
-device ich9-ahci,id=ahci \
|
-device ich9-ahci,id=ahci \
|
||||||
-drive if=none,file=riscv64.img,format=raw,id=mydisk \
|
-drive if=none,file=riscv64.img,format=raw,id=mydisk \
|
||||||
|
@ -866,6 +866,14 @@ config PXA_SERIAL
|
|||||||
If you have a machine based on a Marvell XScale PXA2xx CPU you
|
If you have a machine based on a Marvell XScale PXA2xx CPU you
|
||||||
can enable its onboard serial ports by enabling this option.
|
can enable its onboard serial ports by enabling this option.
|
||||||
|
|
||||||
|
config HTIF_CONSOLE
|
||||||
|
bool "RISC-V HTIF console support"
|
||||||
|
depends on DM_SERIAL && 64BIT
|
||||||
|
help
|
||||||
|
Select this to enable host transfer interface (HTIF) based serial
|
||||||
|
console. The HTIF device is quite common in RISC-V emulators and
|
||||||
|
RISC-V ISS so this driver allows using U-Boot on such platforms.
|
||||||
|
|
||||||
config SIFIVE_SERIAL
|
config SIFIVE_SERIAL
|
||||||
bool "SiFive UART support"
|
bool "SiFive UART support"
|
||||||
depends on DM_SERIAL
|
depends on DM_SERIAL
|
||||||
|
@ -73,6 +73,7 @@ obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
|
|||||||
obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
|
obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
|
||||||
obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
|
obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
|
||||||
obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o
|
obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o
|
||||||
|
obj-$(CONFIG_HTIF_CONSOLE) += serial_htif.o
|
||||||
obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
|
obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
|
||||||
obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
|
obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
|
||||||
|
|
||||||
|
178
drivers/serial/serial_htif.c
Normal file
178
drivers/serial/serial_htif.c
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Ventana Micro Systems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <watchdog.h>
|
||||||
|
#include <asm/global_data.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <serial.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#define HTIF_DATA_BITS 48
|
||||||
|
#define HTIF_DATA_MASK ((1ULL << HTIF_DATA_BITS) - 1)
|
||||||
|
#define HTIF_DATA_SHIFT 0
|
||||||
|
#define HTIF_CMD_BITS 8
|
||||||
|
#define HTIF_CMD_MASK ((1ULL << HTIF_CMD_BITS) - 1)
|
||||||
|
#define HTIF_CMD_SHIFT 48
|
||||||
|
#define HTIF_DEV_BITS 8
|
||||||
|
#define HTIF_DEV_MASK ((1ULL << HTIF_DEV_BITS) - 1)
|
||||||
|
#define HTIF_DEV_SHIFT 56
|
||||||
|
|
||||||
|
#define HTIF_DEV_SYSTEM 0
|
||||||
|
#define HTIF_DEV_CONSOLE 1
|
||||||
|
|
||||||
|
#define HTIF_CONSOLE_CMD_GETC 0
|
||||||
|
#define HTIF_CONSOLE_CMD_PUTC 1
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
# define TOHOST_CMD(dev, cmd, payload) \
|
||||||
|
(((u64)(dev) << HTIF_DEV_SHIFT) | \
|
||||||
|
((u64)(cmd) << HTIF_CMD_SHIFT) | \
|
||||||
|
(u64)(payload))
|
||||||
|
#else
|
||||||
|
# define TOHOST_CMD(dev, cmd, payload) ({ \
|
||||||
|
if ((dev) || (cmd)) \
|
||||||
|
__builtin_trap(); \
|
||||||
|
(payload); })
|
||||||
|
#endif
|
||||||
|
#define FROMHOST_DEV(fromhost_value) \
|
||||||
|
((u64)((fromhost_value) >> HTIF_DEV_SHIFT) & HTIF_DEV_MASK)
|
||||||
|
#define FROMHOST_CMD(fromhost_value) \
|
||||||
|
((u64)((fromhost_value) >> HTIF_CMD_SHIFT) & HTIF_CMD_MASK)
|
||||||
|
#define FROMHOST_DATA(fromhost_value) \
|
||||||
|
((u64)((fromhost_value) >> HTIF_DATA_SHIFT) & HTIF_DATA_MASK)
|
||||||
|
|
||||||
|
struct htif_plat {
|
||||||
|
void *fromhost;
|
||||||
|
void *tohost;
|
||||||
|
int console_char;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __check_fromhost(struct htif_plat *plat)
|
||||||
|
{
|
||||||
|
u64 fh = readq(plat->fromhost);
|
||||||
|
|
||||||
|
if (!fh)
|
||||||
|
return;
|
||||||
|
writeq(0, plat->fromhost);
|
||||||
|
|
||||||
|
/* this should be from the console */
|
||||||
|
if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
|
||||||
|
__builtin_trap();
|
||||||
|
switch (FROMHOST_CMD(fh)) {
|
||||||
|
case HTIF_CONSOLE_CMD_GETC:
|
||||||
|
plat->console_char = 1 + (u8)FROMHOST_DATA(fh);
|
||||||
|
break;
|
||||||
|
case HTIF_CONSOLE_CMD_PUTC:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_trap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __set_tohost(struct htif_plat *plat,
|
||||||
|
u64 dev, u64 cmd, u64 data)
|
||||||
|
{
|
||||||
|
while (readq(plat->tohost))
|
||||||
|
__check_fromhost(plat);
|
||||||
|
writeq(TOHOST_CMD(dev, cmd, data), plat->tohost);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int htif_serial_putc(struct udevice *dev, const char ch)
|
||||||
|
{
|
||||||
|
struct htif_plat *plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_PUTC, ch);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int htif_serial_getc(struct udevice *dev)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
struct htif_plat *plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
if (plat->console_char < 0)
|
||||||
|
__check_fromhost(plat);
|
||||||
|
|
||||||
|
if (plat->console_char >= 0) {
|
||||||
|
ch = plat->console_char;
|
||||||
|
plat->console_char = -1;
|
||||||
|
__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
|
||||||
|
return (ch) ? ch - 1 : -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int htif_serial_pending(struct udevice *dev, bool input)
|
||||||
|
{
|
||||||
|
struct htif_plat *plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
if (!input)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (plat->console_char < 0)
|
||||||
|
__check_fromhost(plat);
|
||||||
|
|
||||||
|
return (plat->console_char >= 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int htif_serial_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct htif_plat *plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
/* Queue first getc request */
|
||||||
|
__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int htif_serial_of_to_plat(struct udevice *dev)
|
||||||
|
{
|
||||||
|
fdt_addr_t addr;
|
||||||
|
struct htif_plat *plat = dev_get_plat(dev);
|
||||||
|
|
||||||
|
addr = dev_read_addr_index(dev, 0);
|
||||||
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
|
return -ENODEV;
|
||||||
|
plat->fromhost = (void *)(uintptr_t)addr;
|
||||||
|
plat->tohost = plat->fromhost + sizeof(u64);
|
||||||
|
|
||||||
|
addr = dev_read_addr_index(dev, 1);
|
||||||
|
if (addr != FDT_ADDR_T_NONE)
|
||||||
|
plat->tohost = (void *)(uintptr_t)addr;
|
||||||
|
|
||||||
|
plat->console_char = -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_serial_ops htif_serial_ops = {
|
||||||
|
.putc = htif_serial_putc,
|
||||||
|
.getc = htif_serial_getc,
|
||||||
|
.pending = htif_serial_pending,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id htif_serial_ids[] = {
|
||||||
|
{ .compatible = "ucb,htif0" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(serial_htif) = {
|
||||||
|
.name = "serial_htif",
|
||||||
|
.id = UCLASS_SERIAL,
|
||||||
|
.of_match = htif_serial_ids,
|
||||||
|
.of_to_plat = htif_serial_of_to_plat,
|
||||||
|
.plat_auto = sizeof(struct htif_plat),
|
||||||
|
.probe = htif_serial_probe,
|
||||||
|
.ops = &htif_serial_ops,
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user