Skip to content

Commit

Permalink
Move portio back into x64 (Bareflank#522)
Browse files Browse the repository at this point in the history
Rather than a generic portio interface for all architectures, with
aarch64 implementing a MMIO-based fake portio, the one item that used
portio generically (serial drivers) has been refactored to provide a
generic implementation of its own IO which is conditionally compiled in
whichever way is sensible for each architecture.

Signed-off-by: Chris Pavlina <pavlinac@ainfosec.com>
  • Loading branch information
Chris Pavlina authored and JaredWright committed Mar 2, 2018
1 parent 4e2c32f commit c5f6fc6
Show file tree
Hide file tree
Showing 15 changed files with 545 additions and 347 deletions.
67 changes: 0 additions & 67 deletions bfvmm/include/intrinsics/aarch64/common/portio_aarch64.h

This file was deleted.

2 changes: 0 additions & 2 deletions bfvmm/include/intrinsics/aarch64/common_aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,4 @@
#ifndef INTRINSICS_AARCH64_COMMON_AARCH64_H
#define INTRINSICS_AARCH64_COMMON_AARCH64_H

#include <intrinsics/aarch64/common/portio_aarch64.h>

#endif
2 changes: 1 addition & 1 deletion bfvmm/include/intrinsics/x86/common/portio_x64.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ extern "C" EXPORT_INTRINSICS void _outsdrep(uint16_t port, uint64_t m32, uint32_

// *INDENT-OFF*

namespace intrinsics
namespace x64
{
namespace portio
{
Expand Down
167 changes: 167 additions & 0 deletions bfvmm/include/serial/serial_port_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
//
// Bareflank Hypervisor
// Copyright (C) 2017 Assured Information Security, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

#ifndef SERIAL_PORT_BASE_H
#define SERIAL_PORT_BASE_H

#include <cstdint>

#include <intrinsics/common.h>

// -----------------------------------------------------------------------------
// Exports
// -----------------------------------------------------------------------------

#include <bfexports.h>

#ifndef STATIC_SERIAL
#ifdef SHARED_SERIAL
#define EXPORT_SERIAL EXPORT_SYM
#else
#define EXPORT_SERIAL IMPORT_SYM
#endif
#else
#define EXPORT_SERIAL
#endif

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4251)
#endif

// -----------------------------------------------------------------------------
// Definitions
// -----------------------------------------------------------------------------

/// Serial port base class
///
/// This class provides an interface to the basic functions of a serial port,
/// and also provides abstracted IO functions to its subclasses.
///
class EXPORT_SERIAL serial_port_base
{
public:
#if defined(BF_X64)
using port_type = x64::portio::port_addr_type;
using value_type_8 = x64::portio::port_8bit_type;
using value_type_32 = x64::portio::port_32bit_type;
#elif defined(BF_AARCH64)
using port_type = uintptr_t;
using value_type_8 = uint8_t;
using value_type_32 = uint32_t;
#else
# error "No serial port implementation for this architecture"
#endif

public:
virtual ~serial_port_base() = default;

/// Port
///
/// @expects none
/// @ensures none
///
/// @return the serial device's port
virtual port_type port() const noexcept = 0;

/// Write Character
///
/// Writes a character to the serial device.
///
/// @expects none
/// @ensures none
///
/// @param c character to write
///
virtual void write(char c) noexcept = 0;

/// Write String
///
/// Writes a string to the serial device.
///
/// @expects none
/// @ensures none
///
/// @param str string to write
///
virtual void write(const std::string &str) noexcept;

/// Write String
///
/// Writes a string to the serial device.
///
/// @expects none
/// @ensures none
///
/// @param str string to write
/// @param len length of the string to write
///
virtual void write(const char *str, size_t len) noexcept;

protected:

/// Read 8 bits from IO
///
/// Reads a value from IO. Implementation is architecture-dependent
///
/// @expects none
/// @ensures none
///
/// @param offset offset (in bytes) from the base address returned by port()
/// @return data loaded from the offset given
///
value_type_8 offset_inb(port_type offset) const noexcept;

/// Read 32 bits from IO
///
/// Reads a value from IO. Implementation is architecture-dependent
///
/// @expects none
/// @ensures none
///
/// @param offset offset (in bytes) from the base address returned by port()
/// @return data loaded from the offset given
///
value_type_32 offset_ind(port_type offset) const noexcept;

/// Write 8 bits to IO
///
/// Writes a value to IO. Implementation is architecture-dependent
///
/// @expects none
/// @ensures none
///
/// @param offset offset (in bytes) from the base address returned by port()
/// @param data value to write to the offset given
///
void offset_outb(port_type offset, value_type_8 data) const noexcept;

/// Write 32 bits to IO
///
/// Writes a value to IO. Implementation is architecture-dependent
///
/// @expects none
/// @ensures none
///
/// @param offset offset (in bytes) from the base address returned by port()
/// @param data value to write to the offset given
///
void offset_outd(port_type offset, value_type_32 data) const noexcept;
};

#endif
87 changes: 31 additions & 56 deletions bfvmm/include/serial/serial_port_ns16550a.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <bfconstants.h>
#include <intrinsics/common.h>
#include <serial/serial_port_base.h>

// -----------------------------------------------------------------------------
// Exports
Expand Down Expand Up @@ -55,32 +56,32 @@
namespace serial_ns16550a
{

constexpr const intrinsics::portio::port_8bit_type dlab = 1U << 7;

constexpr const intrinsics::portio::port_addr_type baud_rate_lo_reg = 0U;
constexpr const intrinsics::portio::port_addr_type baud_rate_hi_reg = 1U;
constexpr const intrinsics::portio::port_addr_type interrupt_en_reg = 1U;
constexpr const intrinsics::portio::port_addr_type fifo_control_reg = 2U;
constexpr const intrinsics::portio::port_addr_type line_control_reg = 3U;
constexpr const intrinsics::portio::port_addr_type line_status_reg = 5U;

constexpr const intrinsics::portio::port_8bit_type fifo_control_enable_fifos = 1U << 0;
constexpr const intrinsics::portio::port_8bit_type fifo_control_clear_recieve_fifo = 1U << 1;
constexpr const intrinsics::portio::port_8bit_type fifo_control_clear_transmit_fifo = 1U << 2;
constexpr const intrinsics::portio::port_8bit_type fifo_control_dma_mode_select = 1U << 3;

constexpr const intrinsics::portio::port_8bit_type line_status_data_ready = 1U << 0;
constexpr const intrinsics::portio::port_8bit_type line_status_overrun_error = 1U << 1;
constexpr const intrinsics::portio::port_8bit_type line_status_parity_error = 1U << 2;
constexpr const intrinsics::portio::port_8bit_type line_status_framing_error = 1U << 3;
constexpr const intrinsics::portio::port_8bit_type line_status_break_interrupt = 1U << 4;
constexpr const intrinsics::portio::port_8bit_type line_status_empty_transmitter = 1U << 5;
constexpr const intrinsics::portio::port_8bit_type line_status_empty_data = 1U << 6;
constexpr const intrinsics::portio::port_8bit_type line_status_recieved_fifo_error = 1U << 7;

constexpr const intrinsics::portio::port_8bit_type line_control_data_mask = 0x03;
constexpr const intrinsics::portio::port_8bit_type line_control_stop_mask = 0x04;
constexpr const intrinsics::portio::port_8bit_type line_control_parity_mask = 0x38;
constexpr const x64::portio::port_8bit_type dlab = 1U << 7;

constexpr const x64::portio::port_addr_type baud_rate_lo_reg = 0U;
constexpr const x64::portio::port_addr_type baud_rate_hi_reg = 1U;
constexpr const x64::portio::port_addr_type interrupt_en_reg = 1U;
constexpr const x64::portio::port_addr_type fifo_control_reg = 2U;
constexpr const x64::portio::port_addr_type line_control_reg = 3U;
constexpr const x64::portio::port_addr_type line_status_reg = 5U;

constexpr const x64::portio::port_8bit_type fifo_control_enable_fifos = 1U << 0;
constexpr const x64::portio::port_8bit_type fifo_control_clear_recieve_fifo = 1U << 1;
constexpr const x64::portio::port_8bit_type fifo_control_clear_transmit_fifo = 1U << 2;
constexpr const x64::portio::port_8bit_type fifo_control_dma_mode_select = 1U << 3;

constexpr const x64::portio::port_8bit_type line_status_data_ready = 1U << 0;
constexpr const x64::portio::port_8bit_type line_status_overrun_error = 1U << 1;
constexpr const x64::portio::port_8bit_type line_status_parity_error = 1U << 2;
constexpr const x64::portio::port_8bit_type line_status_framing_error = 1U << 3;
constexpr const x64::portio::port_8bit_type line_status_break_interrupt = 1U << 4;
constexpr const x64::portio::port_8bit_type line_status_empty_transmitter = 1U << 5;
constexpr const x64::portio::port_8bit_type line_status_empty_data = 1U << 6;
constexpr const x64::portio::port_8bit_type line_status_recieved_fifo_error = 1U << 7;

constexpr const x64::portio::port_8bit_type line_control_data_mask = 0x03;
constexpr const x64::portio::port_8bit_type line_control_stop_mask = 0x04;
constexpr const x64::portio::port_8bit_type line_control_parity_mask = 0x38;

}

Expand All @@ -103,13 +104,8 @@ constexpr const intrinsics::portio::port_8bit_type line_control_parity_mask = 0x
/// Also note, that by default, a FIFO is used / required, and interrupts are
/// disabled.
///
class EXPORT_SERIAL serial_port_ns16550a
class EXPORT_SERIAL serial_port_ns16550a : public serial_port_base
{
public:

using port_type = intrinsics::portio::port_addr_type; ///< Port type
using value_type = intrinsics::portio::port_8bit_type; ///< Value type

public:

/// @cond
Expand Down Expand Up @@ -283,7 +279,7 @@ class EXPORT_SERIAL serial_port_ns16550a
///
/// @return the serial device's port
///
port_type port() const noexcept
virtual port_type port() const noexcept override
{ return m_port; }

/// Write Character
Expand All @@ -295,30 +291,9 @@ class EXPORT_SERIAL serial_port_ns16550a
///
/// @param c character to write
///
void write(char c) noexcept;

/// Write String
///
/// Writes a string to the serial device.
///
/// @expects none
/// @ensures none
///
/// @param str string to write
///
void write(const std::string &str) noexcept;
virtual void write(char c) noexcept override;

/// Write String
///
/// Writes a string to the serial device.
///
/// @expects none
/// @ensures none
///
/// @param str string to write
/// @param len length of the string to write
///
void write(const char *str, size_t len) noexcept;
using serial_port_base::write;

private:

Expand Down

0 comments on commit c5f6fc6

Please sign in to comment.