2022-02-01 07:55:03 +00:00
|
|
|
/*
|
|
|
|
* \brief PCI, PCI-x, PCI-Express configuration declarations
|
|
|
|
* \author Stefan Kalkowski
|
|
|
|
* \date 2021-12-01
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2021 Genode Labs GmbH
|
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __INCLUDE__PCI__CONFIG_H__
|
|
|
|
#define __INCLUDE__PCI__CONFIG_H__
|
|
|
|
|
|
|
|
#include <base/log.h>
|
|
|
|
#include <pci/types.h>
|
|
|
|
#include <util/reconstructible.h>
|
|
|
|
#include <util/mmio.h>
|
|
|
|
|
|
|
|
namespace Pci {
|
|
|
|
struct Config;
|
|
|
|
struct Config_type0;
|
|
|
|
struct Config_type1;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
DEVICES_PER_BUS_MAX = 32,
|
|
|
|
FUNCTION_PER_DEVICE_MAX = 8,
|
|
|
|
FUNCTION_PER_BUS_MAX = DEVICES_PER_BUS_MAX *
|
|
|
|
FUNCTION_PER_DEVICE_MAX,
|
|
|
|
FUNCTION_CONFIG_SPACE_SIZE = 4096,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Pci::Config : Genode::Mmio<0x45>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Vendor : Register<0x0, 16>
|
|
|
|
{
|
|
|
|
enum { INVALID = 0xffff };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Device : Register<0x2, 16> {};
|
|
|
|
|
|
|
|
struct Command : Register<0x4, 16>
|
|
|
|
{
|
2022-09-09 09:46:27 +00:00
|
|
|
struct Io_space_enable : Bitfield<0, 1> {};
|
|
|
|
struct Memory_space_enable : Bitfield<1, 1> {};
|
|
|
|
struct Bus_master_enable : Bitfield<2, 1> {};
|
|
|
|
struct Special_cycle_enable : Bitfield<3, 1> {};
|
|
|
|
struct Memory_write_invalidate : Bitfield<4, 1> {};
|
|
|
|
struct Vga_palette_snoop : Bitfield<5, 1> {};
|
|
|
|
struct Parity_error_response : Bitfield<6, 1> {};
|
|
|
|
struct Idsel : Bitfield<7, 1> {};
|
|
|
|
struct Serror_enable : Bitfield<8, 1> {};
|
|
|
|
struct Fast_back_to_back_enable : Bitfield<9, 1> {};
|
|
|
|
struct Interrupt_enable : Bitfield<10, 1> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Status : Register<0x6, 16>
|
|
|
|
{
|
|
|
|
struct Interrupt : Bitfield<3,1> {};
|
|
|
|
struct Capabilities : Bitfield<4,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Class_code_rev_id : Register<0x8, 32>
|
|
|
|
{
|
2022-07-25 12:04:25 +00:00
|
|
|
struct Revision : Bitfield<0, 8> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
struct Class_code : Bitfield<8, 24> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Iface_class_code : Register<0x9, 8> {};
|
|
|
|
struct Sub_class_code : Register<0xa, 8> {};
|
|
|
|
struct Base_class_code : Register<0xb, 8>
|
|
|
|
{
|
|
|
|
enum { BRIDGE = 6 };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Header_type : Register<0xe, 8>
|
|
|
|
{
|
|
|
|
struct Type : Bitfield<0,7> {};
|
|
|
|
struct Multi_function : Bitfield<7,1> {};
|
|
|
|
};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Base_address : Mmio<0x8>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Bar_32bit : Register<0, 32>
|
|
|
|
{
|
|
|
|
struct Memory_space_indicator : Bitfield<0,1>
|
|
|
|
{
|
|
|
|
enum { MEMORY = 0, IO = 1 };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Memory_type : Bitfield<1,2>
|
|
|
|
{
|
|
|
|
enum { SIZE_32BIT = 0, SIZE_64BIT = 2 };
|
|
|
|
};
|
|
|
|
|
2022-09-28 11:56:17 +00:00
|
|
|
struct Memory_prefetchable : Bitfield<3,1> {};
|
|
|
|
|
2022-02-01 07:55:03 +00:00
|
|
|
struct Io_base : Bitfield<2, 30> {};
|
|
|
|
struct Memory_base : Bitfield<7, 25> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Upper_bits : Register<0x4, 32> { };
|
|
|
|
|
2022-10-07 15:10:05 +00:00
|
|
|
Bar_32bit::access_t _conf_value { 0 };
|
2022-02-01 07:55:03 +00:00
|
|
|
|
2022-10-10 13:17:55 +00:00
|
|
|
template <typename REG>
|
|
|
|
typename REG::access_t _get_and_set(typename REG::access_t value)
|
|
|
|
{
|
|
|
|
write<REG>(0xffffffff);
|
|
|
|
typename REG::access_t ret = read<REG>();
|
|
|
|
write<REG>(value);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-10-07 15:10:05 +00:00
|
|
|
Bar_32bit::access_t _conf()
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2022-10-07 15:10:05 +00:00
|
|
|
/*
|
|
|
|
* Initialize _conf_value on demand only to prevent read-write
|
|
|
|
* operations on BARs of invalid devices at construction time.
|
|
|
|
*/
|
2022-10-10 13:17:55 +00:00
|
|
|
if (!_conf_value)
|
|
|
|
_conf_value = _get_and_set<Bar_32bit>(read<Bar_32bit>());
|
2022-10-07 15:10:05 +00:00
|
|
|
return _conf_value;
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
Base_address(Genode::Byte_range_ptr const &range) : Mmio(range) { }
|
2022-10-07 15:10:05 +00:00
|
|
|
|
|
|
|
bool valid() { return _conf() != 0; }
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
bool memory() {
|
2022-10-07 15:10:05 +00:00
|
|
|
return !Bar_32bit::Memory_space_indicator::get(_conf()); }
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
bool bit64()
|
|
|
|
{
|
2022-10-07 15:10:05 +00:00
|
|
|
return Bar_32bit::Memory_type::get(_conf()) ==
|
2022-02-01 07:55:03 +00:00
|
|
|
Bar_32bit::Memory_type::SIZE_64BIT;
|
|
|
|
}
|
|
|
|
|
2022-09-28 11:56:17 +00:00
|
|
|
bool prefetchable() {
|
2022-10-07 15:10:05 +00:00
|
|
|
return Bar_32bit::Memory_prefetchable::get(_conf()); }
|
2022-09-28 11:56:17 +00:00
|
|
|
|
2023-06-29 21:12:07 +00:00
|
|
|
Genode::uint64_t size()
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2023-06-29 21:12:07 +00:00
|
|
|
if (memory()) {
|
|
|
|
Genode::uint64_t size = 1 + ~Bar_32bit::Memory_base::masked(_conf());
|
|
|
|
if (bit64())
|
|
|
|
size += ((Genode::uint64_t)~_get_and_set<Upper_bits>(read<Upper_bits>()))<<32;
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 1 + ~Bar_32bit::Io_base::masked(_conf());
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Genode::uint64_t addr()
|
|
|
|
{
|
2022-07-25 11:47:56 +00:00
|
|
|
if (memory())
|
|
|
|
return (bit64()
|
|
|
|
? ((Genode::uint64_t)read<Upper_bits>()<<32) : 0UL)
|
|
|
|
| Bar_32bit::Memory_base::masked(read<Bar_32bit>());
|
|
|
|
else
|
|
|
|
return Bar_32bit::Io_base::masked(read<Bar_32bit>());
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
2022-10-10 13:17:55 +00:00
|
|
|
|
|
|
|
void set(Genode::uint64_t v)
|
|
|
|
{
|
|
|
|
if (!valid() || v == addr())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (memory()) {
|
|
|
|
if (bit64())
|
|
|
|
_get_and_set<Upper_bits>((Upper_bits::access_t)(v >> 32));
|
|
|
|
_get_and_set<Bar_32bit>(Bar_32bit::Memory_base::masked(v & ~0U));
|
|
|
|
} else
|
|
|
|
_get_and_set<Bar_32bit>(Bar_32bit::Io_base::masked(v & ~0U));
|
|
|
|
}
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum Base_addresses {
|
|
|
|
BASE_ADDRESS_0 = 0x10,
|
|
|
|
BASE_ADDRESS_COUNT_TYPE_0 = 6,
|
|
|
|
BASE_ADDRESS_COUNT_TYPE_1 = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Capability_pointer : Register<0x34, 8> {};
|
|
|
|
|
2022-05-16 13:55:15 +00:00
|
|
|
struct Irq_line : Register<0x3c, 8>
|
|
|
|
{
|
|
|
|
enum { UNKNOWN = 0xff };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Irq_pin : Register<0x3d, 8>
|
|
|
|
{
|
|
|
|
enum { NO_INT = 0, INTA, INTB, INTC, INTD };
|
|
|
|
};
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
** PCI Capabilities **
|
|
|
|
**********************/
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
template <Genode::size_t SIZE>
|
|
|
|
struct Pci_capability : Genode::Mmio<SIZE>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Id : Register<0,8>
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
POWER_MANAGEMENT = 0x1,
|
|
|
|
AGP = 0x2,
|
|
|
|
VITAL_PRODUCT = 0x3,
|
|
|
|
MSI = 0x5,
|
|
|
|
VENDOR = 0x9,
|
|
|
|
DEBUG = 0xa,
|
|
|
|
BRIDGE_SUB = 0xd,
|
|
|
|
PCI_E = 0x10,
|
|
|
|
MSI_X = 0x11,
|
|
|
|
SATA = 0x12,
|
|
|
|
ADVANCED = 0x13,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Pointer : Register<1,8> {};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Mmio<SIZE>::Mmio;
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Pci_capability_header : Pci_capability<0x2>
|
|
|
|
{
|
|
|
|
using Pci_capability::Pci_capability;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Power_management_capability : Pci_capability<0x8>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2022-10-10 13:17:55 +00:00
|
|
|
struct Capabilities : Register<0x2, 16> {};
|
|
|
|
|
2022-02-01 07:55:03 +00:00
|
|
|
struct Control_status : Register<0x4, 16>
|
|
|
|
{
|
2022-10-10 13:17:55 +00:00
|
|
|
struct Power_state : Bitfield<0, 2>
|
|
|
|
{
|
|
|
|
enum { D0, D1, D2, D3 };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct No_soft_reset : Bitfield<3, 1> {};
|
|
|
|
struct Pme_status : Bitfield<15,1> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
2022-10-10 13:17:55 +00:00
|
|
|
|
|
|
|
struct Data : Register<0x7, 8> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
using Pci_capability::Pci_capability;
|
2022-10-10 13:17:55 +00:00
|
|
|
|
|
|
|
bool power_on(Delayer & delayer)
|
|
|
|
{
|
|
|
|
using Reg = Control_status::Power_state;
|
|
|
|
if (read<Reg>() == Reg::D0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
write<Reg>(Reg::D0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PCI Express 4.3 - 5.3.1.4. D3 State
|
|
|
|
*
|
|
|
|
* "Unless Readiness Notifications mechanisms are used ..."
|
|
|
|
* "a minimum recovery time following a D3 hot → D0 transition of"
|
|
|
|
* "at least 10 ms ..."
|
|
|
|
*/
|
|
|
|
delayer.usleep(10'000);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void power_off()
|
|
|
|
{
|
|
|
|
using Reg = Control_status::Power_state;
|
|
|
|
if (read<Reg>() != Reg::D3) write<Reg>(Reg::D3);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool soft_reset()
|
|
|
|
{
|
|
|
|
return !read<Control_status::No_soft_reset>();
|
|
|
|
}
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Msi_capability : Pci_capability<0xe>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Control : Register<0x2, 16>
|
|
|
|
{
|
|
|
|
struct Enable : Bitfield<0,1> {};
|
|
|
|
struct Multi_message_capable : Bitfield<1,3> {};
|
|
|
|
struct Multi_message_enable : Bitfield<4,3> {};
|
|
|
|
struct Large_address_capable : Bitfield<7,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Address_32 : Register<0x4, 32> {};
|
|
|
|
struct Data_32 : Register<0x8, 16> {};
|
|
|
|
|
|
|
|
struct Address_64_lower : Register<0x4, 32> {};
|
|
|
|
struct Address_64_upper : Register<0x8, 32> {};
|
|
|
|
struct Data_64 : Register<0xc, 16> {};
|
|
|
|
|
|
|
|
using Pci_capability::Pci_capability;
|
|
|
|
|
|
|
|
void enable(Genode::addr_t address,
|
|
|
|
Genode::uint16_t data)
|
|
|
|
{
|
|
|
|
if (read<Control::Large_address_capable>()) {
|
|
|
|
Genode::uint64_t addr = address;
|
|
|
|
write<Address_64_upper>((Genode::uint32_t)(addr >> 32));
|
|
|
|
write<Address_64_lower>((Genode::uint32_t)addr);
|
|
|
|
write<Data_64>(data);
|
|
|
|
} else {
|
|
|
|
write<Address_32>((Genode::uint32_t)address);
|
|
|
|
write<Data_32>(data);
|
|
|
|
}
|
|
|
|
write<Control::Enable>(1);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Msi_x_capability : Pci_capability<0xc>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Control : Register<0x2, 16>
|
|
|
|
{
|
2022-10-05 16:25:55 +00:00
|
|
|
struct Slots : Bitfield<0, 10> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
struct Size : Bitfield<0, 11> {};
|
|
|
|
struct Function_mask : Bitfield<14, 1> {};
|
|
|
|
struct Enable : Bitfield<15, 1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Table : Register<0x4, 32>
|
|
|
|
{
|
|
|
|
struct Bar_index : Bitfield<0, 3> {};
|
|
|
|
struct Offset : Bitfield<3, 29> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Pending_bit_array : Register<0x8, 32>
|
|
|
|
{
|
|
|
|
struct Bar_index : Bitfield<0, 3> {};
|
|
|
|
struct Offset : Bitfield<3, 29> {};
|
|
|
|
};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Table_entry : Genode::Mmio<0x10>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2022-10-05 16:25:55 +00:00
|
|
|
enum { SIZE = 16 };
|
|
|
|
|
2022-02-01 07:55:03 +00:00
|
|
|
struct Address_64_lower : Register<0x0, 32> { };
|
|
|
|
struct Address_64_upper : Register<0x4, 32> { };
|
|
|
|
struct Data : Register<0x8, 32> { };
|
|
|
|
struct Vector_control : Register<0xc, 32>
|
|
|
|
{
|
|
|
|
struct Mask : Bitfield <0, 1> { };
|
|
|
|
};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Mmio::Mmio;
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
using Pci_capability::Pci_capability;
|
2022-10-05 16:25:55 +00:00
|
|
|
|
|
|
|
Genode::uint8_t bar() {
|
|
|
|
return (Genode::uint8_t) read<Table::Bar_index>(); }
|
|
|
|
|
|
|
|
Genode::size_t table_offset() {
|
|
|
|
return read<Table::Offset>() << 3; }
|
|
|
|
|
|
|
|
unsigned slots() { return read<Control::Slots>(); }
|
|
|
|
|
|
|
|
void enable()
|
|
|
|
{
|
|
|
|
Control::access_t ctrl = read<Control>();
|
|
|
|
Control::Function_mask::set(ctrl, 0);
|
|
|
|
Control::Enable::set(ctrl, 1);
|
|
|
|
write<Control>(ctrl);
|
|
|
|
}
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Pci_express_capability : Pci_capability<0x3c>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2022-10-10 13:17:55 +00:00
|
|
|
struct Capabilities : Register<0x2, 16> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
|
2022-10-10 13:17:55 +00:00
|
|
|
struct Device_capabilities : Register<0x4, 32>
|
|
|
|
{
|
|
|
|
struct Function_level_reset : Bitfield<28,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Device_control : Register<0x8, 16>
|
|
|
|
{
|
|
|
|
struct Function_level_reset : Bitfield<15,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Device_status : Register<0xa, 16>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Correctable_error : Bitfield<0, 1> {};
|
|
|
|
struct Non_fatal_error : Bitfield<1, 1> {};
|
|
|
|
struct Fatal_error : Bitfield<2, 1> {};
|
|
|
|
struct Unsupported_request : Bitfield<3, 1> {};
|
|
|
|
struct Aux_power : Bitfield<4, 1> {};
|
|
|
|
struct Transactions_pending : Bitfield<5, 1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Link_capabilities : Register<0xc, 32>
|
|
|
|
{
|
|
|
|
struct Max_link_speed : Bitfield<0, 4> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Link_control : Register<0x10, 16>
|
|
|
|
{
|
|
|
|
struct Lbm_irq_enable : Bitfield<10,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Link_status : Register<0x12, 16>
|
|
|
|
{
|
|
|
|
struct Lbm_status : Bitfield<10,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Slot_capabilities : Register<0x14, 32> {};
|
|
|
|
struct Slot_control : Register<0x18, 16> {};
|
|
|
|
struct Slot_status : Register<0x1a, 16> {};
|
|
|
|
|
|
|
|
struct Root_control : Register<0x1c, 16>
|
|
|
|
{
|
|
|
|
struct Pme_irq_enable : Bitfield<3,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Root_status : Register<0x20, 32>
|
|
|
|
{
|
|
|
|
struct Pme : Bitfield<16,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Device_capabilities_2 : Register<0x24, 32> {};
|
|
|
|
struct Device_control_2 : Register<0x28, 16> {};
|
|
|
|
struct Device_status_2 : Register<0x2a, 16> {};
|
|
|
|
struct Link_capabilities_2 : Register<0x2c, 32> {};
|
|
|
|
|
|
|
|
struct Link_control_2 : Register<0x30, 16>
|
|
|
|
{
|
|
|
|
struct Link_speed : Bitfield<0, 4> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Link_status_2 : Register<0x32, 16> {};
|
|
|
|
struct Slot_capabilities_2 : Register<0x34, 32> {};
|
|
|
|
struct Slot_control_2 : Register<0x38, 16> {};
|
|
|
|
struct Slot_status_2 : Register<0x3a, 16> {};
|
|
|
|
|
|
|
|
using Pci_capability::Pci_capability;
|
|
|
|
|
|
|
|
void power_management_event_enable()
|
|
|
|
{
|
|
|
|
write<Root_status::Pme>(1);
|
|
|
|
write<Root_control::Pme_irq_enable>(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
void clear_dev_errors()
|
|
|
|
{
|
|
|
|
Device_status::access_t v = read<Device_status>();
|
|
|
|
Device_status::Correctable_error::set(v,1);
|
|
|
|
Device_status::Non_fatal_error::set(v,1);
|
|
|
|
Device_status::Fatal_error::set(v,1);
|
|
|
|
Device_status::Unsupported_request::set(v,1);
|
|
|
|
Device_status::Aux_power::set(v,1);
|
|
|
|
write<Device_status>(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void link_bandwidth_management_enable()
|
|
|
|
{
|
|
|
|
write<Link_status::Lbm_status>(1);
|
|
|
|
write<Link_control::Lbm_irq_enable>(1);
|
|
|
|
}
|
2022-10-10 13:17:55 +00:00
|
|
|
|
|
|
|
void reset(Delayer & delayer)
|
|
|
|
{
|
|
|
|
if (!read<Device_capabilities::Function_level_reset>())
|
|
|
|
return;
|
|
|
|
write<Device_control::Function_level_reset>(1);
|
|
|
|
try {
|
|
|
|
wait_for(Attempts(100), Microseconds(10000), delayer,
|
|
|
|
Device_status::Transactions_pending::Equal(0));
|
|
|
|
} catch(Polling_timeout) { }
|
|
|
|
}
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************
|
|
|
|
** PCI-E extended capabilities **
|
|
|
|
*********************************/
|
|
|
|
|
|
|
|
enum { PCI_E_EXTENDED_CAPS_OFFSET = 0x100U };
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
template<Genode::size_t SIZE>
|
|
|
|
struct Pci_express_extended_capability : Genode::Mmio<SIZE>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
2022-09-28 15:01:45 +00:00
|
|
|
struct Id : Register<0x0, 16>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
enum {
|
|
|
|
INVALID = 0x0,
|
|
|
|
ADVANCED_ERROR_REPORTING = 0x1,
|
|
|
|
VIRTUAL_CHANNEL = 0x2,
|
|
|
|
DEVICE_SERIAL_NUMBER = 0x3,
|
|
|
|
POWER_BUDGETING = 0x4,
|
|
|
|
VENDOR = 0xb,
|
|
|
|
MULTI_ROOT_IO_VIRT = 0x11,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-09-28 15:01:45 +00:00
|
|
|
struct Next_and_version : Register<0x2, 16>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Offset : Bitfield<4, 12> {};
|
|
|
|
};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Mmio<SIZE>::Mmio;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Pci_express_extended_capability_header : Pci_express_extended_capability<0x4>
|
|
|
|
{
|
|
|
|
using Pci_express_extended_capability::Pci_express_extended_capability;
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
struct Advanced_error_reporting_capability : Pci_express_extended_capability<0x34>
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
struct Uncorrectable_error_status : Register<0x4, 32> {};
|
|
|
|
struct Correctable_error_status : Register<0x10, 32> {};
|
|
|
|
|
|
|
|
struct Root_error_command : Register<0x2c, 32>
|
|
|
|
{
|
|
|
|
struct Correctable_error_enable : Bitfield<0,1> {};
|
|
|
|
struct Non_fatal_error_enable : Bitfield<1,1> {};
|
|
|
|
struct Fatal_error_enable : Bitfield<2,1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Root_error_status : Register<0x30, 32> {};
|
|
|
|
|
|
|
|
using Pci_express_extended_capability::Pci_express_extended_capability;
|
|
|
|
|
|
|
|
void enable()
|
|
|
|
{
|
|
|
|
Root_error_command::access_t v = 0;
|
|
|
|
Root_error_command::Correctable_error_enable::set(v,1);
|
|
|
|
Root_error_command::Non_fatal_error_enable::set(v,1);
|
|
|
|
Root_error_command::Fatal_error_enable::set(v,1);
|
|
|
|
write<Root_error_command>(v);
|
|
|
|
};
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
write<Root_error_status>(read<Root_error_status>());
|
|
|
|
write<Correctable_error_status>(read<Correctable_error_status>());
|
|
|
|
write<Uncorrectable_error_status>(read<Uncorrectable_error_status>());
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
Genode::Constructible<Power_management_capability> power_cap {};
|
|
|
|
Genode::Constructible<Msi_capability> msi_cap {};
|
|
|
|
Genode::Constructible<Msi_x_capability> msi_x_cap {};
|
|
|
|
Genode::Constructible<Pci_express_capability> pci_e_cap {};
|
|
|
|
Genode::Constructible<Advanced_error_reporting_capability> adv_err_cap {};
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
Base_address bar0 { Mmio::range_at(BASE_ADDRESS_0) };
|
|
|
|
Base_address bar1 { Mmio::range_at(BASE_ADDRESS_0 + 0x4) };
|
2022-05-16 13:55:15 +00:00
|
|
|
|
2022-02-01 07:55:03 +00:00
|
|
|
void clear_errors() {
|
|
|
|
if (adv_err_cap.constructed()) adv_err_cap->clear(); }
|
|
|
|
|
|
|
|
void scan()
|
|
|
|
{
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
if (!read<Status::Capabilities>())
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint16_t off = read<Capability_pointer>();
|
|
|
|
while (off) {
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Capability_header = Pci_capability_header;
|
|
|
|
Capability_header cap(Mmio::range_at(off));
|
|
|
|
switch(cap.read<Capability_header::Id>()) {
|
|
|
|
case Capability_header::Id::POWER_MANAGEMENT:
|
|
|
|
power_cap.construct(Mmio::range_at(off)); break;
|
|
|
|
case Capability_header::Id::MSI:
|
|
|
|
msi_cap.construct(Mmio::range_at(off)); break;
|
|
|
|
case Capability_header::Id::MSI_X:
|
|
|
|
msi_x_cap.construct(Mmio::range_at(off)); break;
|
|
|
|
case Capability_header::Id::PCI_E:
|
|
|
|
pci_e_cap.construct(Mmio::range_at(off)); break;
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
default:
|
2022-09-28 15:01:45 +00:00
|
|
|
/* ignore unhandled capability */ ;
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
off = cap.read<Capability_header::Pointer>();
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!pci_e_cap.constructed())
|
|
|
|
return;
|
|
|
|
|
|
|
|
off = PCI_E_EXTENDED_CAPS_OFFSET;
|
|
|
|
while (off) {
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Capability_header = Pci_express_extended_capability_header;
|
|
|
|
Capability_header cap(Mmio::range_at(off));
|
|
|
|
switch (cap.read<Capability_header::Id>()) {
|
|
|
|
case Capability_header::Id::INVALID:
|
2022-02-01 07:55:03 +00:00
|
|
|
return;
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
case Capability_header::Id::ADVANCED_ERROR_REPORTING:
|
|
|
|
adv_err_cap.construct(Mmio::range_at(off)); break;
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
default:
|
2022-09-28 15:01:45 +00:00
|
|
|
/* ignore unhandled extended capability */ ;
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
off = cap.read<Capability_header::Next_and_version::Offset>();
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
using Mmio::Mmio;
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
bool valid() {
|
|
|
|
return read<Vendor>() != Vendor::INVALID; }
|
|
|
|
|
|
|
|
bool bridge()
|
|
|
|
{
|
|
|
|
return read<Header_type::Type>() == 1 ||
|
|
|
|
read<Base_class_code>() == Base_class_code::BRIDGE;
|
|
|
|
}
|
|
|
|
|
2024-05-22 15:22:53 +00:00
|
|
|
void for_each_bar(auto const &memory_fn, auto const &io_fn)
|
2022-02-01 07:55:03 +00:00
|
|
|
{
|
|
|
|
Genode::size_t const reg_cnt =
|
|
|
|
(read<Header_type::Type>()) ? BASE_ADDRESS_COUNT_TYPE_1
|
|
|
|
: BASE_ADDRESS_COUNT_TYPE_0;
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < reg_cnt; i++) {
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
Base_address reg0 { Mmio::range_at(BASE_ADDRESS_0 + i*0x4) };
|
2022-02-01 07:55:03 +00:00
|
|
|
if (!reg0.valid())
|
|
|
|
continue;
|
|
|
|
if (reg0.memory()) {
|
2024-05-22 15:22:53 +00:00
|
|
|
memory_fn(reg0.addr(), reg0.size(), i, reg0.prefetchable());
|
2022-02-01 07:55:03 +00:00
|
|
|
if (reg0.bit64()) i++;
|
|
|
|
} else
|
2024-05-22 15:22:53 +00:00
|
|
|
io_fn(reg0.addr(), reg0.size(), i);
|
2022-02-01 07:55:03 +00:00
|
|
|
}
|
|
|
|
};
|
2022-10-10 13:17:55 +00:00
|
|
|
|
|
|
|
void set_bar_address(unsigned idx, Genode::uint64_t addr)
|
|
|
|
{
|
|
|
|
if (idx > 5 || (idx > 1 && bridge()))
|
|
|
|
return;
|
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
Base_address bar { Mmio::range_at(BASE_ADDRESS_0 + idx*0x4) };
|
2022-10-10 13:17:55 +00:00
|
|
|
bar.set(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void power_on(Delayer & delayer)
|
|
|
|
{
|
|
|
|
if (!power_cap.constructed() || !power_cap->power_on(delayer))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (power_cap->soft_reset() && pci_e_cap.constructed())
|
|
|
|
pci_e_cap->reset(delayer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void power_off()
|
|
|
|
{
|
|
|
|
if (power_cap.constructed()) power_cap->power_off();
|
|
|
|
}
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Pci::Config_type0 : Pci::Config
|
|
|
|
{
|
|
|
|
struct Expansion_rom_base_addr : Register<0x30, 32> {};
|
|
|
|
|
|
|
|
using Pci::Config::Config;
|
2022-05-16 13:55:15 +00:00
|
|
|
|
mmio: upper-bounds checks
The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and
Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each
type that derives from one of these classes, it is now statically checked that
the range of each Genode::Register::Register- and
Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE).
That said, SIZE is the minimum size of the memory region provided to the above
mentioned Mmio classes in order to avoid page faults or memory corruption when
accessing the registers and register arrays declared inside.
Note, that the range end of a register array is not the end of the last item
but the end of integer access that is used for accessing the last bit in the
last item.
The constructors of Genode::Mmio, Genode::Attached_mmio, and
Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is
expected to be the range of the backing memory region. In each type that derives
from on of these classes, it is now dynamically checked that 'range.num_bytes
>= SIZE', thereby implementing the above mention protection against page faults
and memory corruption.
The rest of the commit adapts the code throughout the Genode Labs repositories
regarding the changes. Note that for that code inside Core, the commits mostly
uses a simplified approach by constructing MMIO objects with range
[base..base+SIZE) and not with a mapping- or specification-related range size.
This should be fixed in the future.
Furthermore, there are types that derive from an MMIO class but don't declare
any registers or register arrays (especially with Platform::Device::Mmio). In
this case SIZE is set to 0. This way, the parameters must be actively corrected
by someone who later wants to add registers or register arrays, plus the places
can be easily found by grep'ing for Mmio<0>.
Fix #4081
2024-01-10 14:08:53 +00:00
|
|
|
Base_address bar2 { Mmio::range_at(BASE_ADDRESS_0 + 0x8 ) };
|
|
|
|
Base_address bar3 { Mmio::range_at(BASE_ADDRESS_0 + 0xc ) };
|
|
|
|
Base_address bar4 { Mmio::range_at(BASE_ADDRESS_0 + 0x10) };
|
|
|
|
Base_address bar5 { Mmio::range_at(BASE_ADDRESS_0 + 0x14) };
|
2022-07-25 12:04:25 +00:00
|
|
|
|
|
|
|
struct Subsystem_vendor : Register<0x2c, 16> { };
|
|
|
|
struct Subsystem_device : Register<0x2e, 16> { };
|
2022-02-01 07:55:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Pci::Config_type1 : Pci::Config
|
|
|
|
{
|
|
|
|
struct Sec_lat_timer_bus : Register<0x18, 32>
|
|
|
|
{
|
|
|
|
struct Primary_bus : Bitfield<0, 8> {};
|
|
|
|
struct Secondary_bus : Bitfield<8, 8> {};
|
|
|
|
struct Sub_bus : Bitfield<16, 8> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Io_base_limit : Register<0x1c, 16> {};
|
|
|
|
|
2022-05-16 13:55:15 +00:00
|
|
|
struct Memory_base : Register<0x20, 16> {};
|
|
|
|
struct Memory_limit : Register<0x22, 16> {};
|
2022-02-01 07:55:03 +00:00
|
|
|
|
|
|
|
struct Prefetchable_memory_base : Register<0x24, 32> {};
|
|
|
|
struct Prefetchable_memory_base_upper : Register<0x28, 32> {};
|
|
|
|
struct Prefetchable_memory_limit_upper : Register<0x2c, 32> {};
|
|
|
|
|
|
|
|
struct Io_base_limit_upper : Register<0x30, 32> {};
|
|
|
|
|
|
|
|
struct Expansion_rom_base_addr : Register<0x38, 32> {};
|
|
|
|
|
|
|
|
struct Bridge_control : Register<0x3e, 16>
|
|
|
|
{
|
|
|
|
struct Serror : Bitfield<1, 1> {};
|
|
|
|
};
|
|
|
|
|
|
|
|
using Pci::Config::Config;
|
|
|
|
|
|
|
|
bus_t primary_bus_number() {
|
|
|
|
return (bus_t) read<Sec_lat_timer_bus::Primary_bus>(); }
|
|
|
|
|
|
|
|
bus_t secondary_bus_number() {
|
|
|
|
return (bus_t) read<Sec_lat_timer_bus::Secondary_bus>(); }
|
|
|
|
|
|
|
|
bus_t subordinate_bus_number() {
|
|
|
|
return (bus_t) read<Sec_lat_timer_bus::Sub_bus>(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* __INCLUDE__PCI__CONFIG_H__ */
|