arch/io.h: Add port I/O functions to other architectures
The QEMU Bochs display driver and the QEMU Firmware Configuration interface code (in the qemu-i440fx mainboard dir) were written for x86. These devices are available in QEMU VMs of other architectures as well, so we want to port them to be independent from x86. The main problem is that the drivers use x86 port I/O functions to communicate with devices over PCI I/O space. These are currently not available for ARM* and RISC-V, although it is often still possible to access PCI I/O ports over MMIO through a translator. Add implementations of port I/O functions that work with PCI I/O space on these architectures as well, assuming there is such a translator at a known address configured at build-time. Change-Id: If7d9177283e8c692088ba8e30d6dfe52623c8cb9 Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/80372 Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
e4d73ec578
commit
4e00e6291a
8
src/arch/arm/include/armv4/arch/io.h
Normal file
8
src/arch/arm/include/armv4/arch/io.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ARCH_IO_H__
|
||||
#define __ARCH_IO_H__
|
||||
|
||||
#include <arch-generic/io.h>
|
||||
|
||||
#endif
|
8
src/arch/arm/include/armv7/arch/io.h
Normal file
8
src/arch/arm/include/armv7/arch/io.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ARCH_IO_H__
|
||||
#define __ARCH_IO_H__
|
||||
|
||||
#include <arch-generic/io.h>
|
||||
|
||||
#endif
|
8
src/arch/arm64/include/armv8/arch/io.h
Normal file
8
src/arch/arm64/include/armv8/arch/io.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ARCH_IO_H__
|
||||
#define __ARCH_IO_H__
|
||||
|
||||
#include <arch-generic/io.h>
|
||||
|
||||
#endif
|
8
src/arch/riscv/include/arch/io.h
Normal file
8
src/arch/riscv/include/arch/io.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ARCH_IO_H__
|
||||
#define __ARCH_IO_H__
|
||||
|
||||
#include <arch-generic/io.h>
|
||||
|
||||
#endif
|
@ -525,6 +525,12 @@ config PCI
|
||||
bool
|
||||
default n
|
||||
|
||||
config PCI_IOBASE
|
||||
hex
|
||||
help
|
||||
The memory address of a memory-mapped translator that lets the
|
||||
CPU communicate with peripheral devices over PCI I/O space.
|
||||
|
||||
if PCI
|
||||
|
||||
config DOMAIN_RESOURCE_32BIT_LIMIT
|
||||
|
96
src/include/arch-generic/io.h
Normal file
96
src/include/arch-generic/io.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* I/O device access primitives. Simplified based on related U-Boot code,
|
||||
* which is in turn based on early versions from the Linux kernel:
|
||||
*
|
||||
* Copyright (C) 1996-2000 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_GENERIC_IO_H__
|
||||
#define __ARCH_GENERIC_IO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <endian.h>
|
||||
#include <arch/mmio.h>
|
||||
|
||||
#define __io(a) (void *)(uintptr_t)(CONFIG_PCI_IOBASE + a)
|
||||
|
||||
static inline void outb(uint8_t value, uint16_t port)
|
||||
{
|
||||
write8(__io(port), value);
|
||||
}
|
||||
|
||||
static inline void outw(uint16_t value, uint16_t port)
|
||||
{
|
||||
write16(__io(port), cpu_to_le16(value));
|
||||
}
|
||||
|
||||
static inline void outl(uint32_t value, uint16_t port)
|
||||
{
|
||||
write32(__io(port), cpu_to_le32(value));
|
||||
}
|
||||
|
||||
static inline uint8_t inb(uint16_t port)
|
||||
{
|
||||
return read8(__io(port));
|
||||
}
|
||||
|
||||
static inline uint16_t inw(uint16_t port)
|
||||
{
|
||||
return le16_to_cpu(read16(__io(port)));
|
||||
}
|
||||
|
||||
static inline uint32_t inl(uint16_t port)
|
||||
{
|
||||
return le32_to_cpu(read32(__io(port)));
|
||||
}
|
||||
|
||||
static inline void outsb(uint16_t port, const void *addr, unsigned long count)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)addr;
|
||||
while (count--)
|
||||
write8(__io(port), *buf++);
|
||||
}
|
||||
|
||||
static inline void outsw(uint16_t port, const void *addr, unsigned long count)
|
||||
{
|
||||
uint16_t *buf = (uint16_t *)addr;
|
||||
while (count--)
|
||||
write16(__io(port), *buf++);
|
||||
}
|
||||
|
||||
static inline void outsl(uint16_t port, const void *addr, unsigned long count)
|
||||
{
|
||||
uint32_t *buf = (uint32_t *)addr;
|
||||
while (count--)
|
||||
write32(__io(port), *buf++);
|
||||
}
|
||||
|
||||
static inline void insb(uint16_t port, void *addr, unsigned long count)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)addr;
|
||||
while (count--)
|
||||
*buf++ = read8(__io(port));
|
||||
}
|
||||
|
||||
static inline void insw(uint16_t port, void *addr, unsigned long count)
|
||||
{
|
||||
uint16_t *buf = (uint16_t *)addr;
|
||||
while (count--)
|
||||
*buf++ = read16(__io(port));
|
||||
}
|
||||
|
||||
static inline void insl(uint16_t port, void *addr, unsigned long count)
|
||||
{
|
||||
uint32_t *buf = (uint32_t *)addr;
|
||||
while (count--)
|
||||
*buf++ = read32(__io(port));
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user