Skip to content
Snippets Groups Projects
Commit a1aa5243 authored by Asias He's avatar Asias He Committed by Avi Kivity
Browse files

ahci: Relax _cmd_table and _recv_fis alignment


AHCI spec says cmd_table need to be aligned to 128 bytes, respect it.

AHCI spec does not specify the alignment requirement of _cmd_list and
_recv_fis. To be safe, we align to their size, i.e. 1024 and 256 bytes.

This fixes the issue reported by Roman Shaposhnik.

   $ capstan run -p vbox
   Created instance: i1398297574
   OSv v0.07
   Assertion failed: !(reinterpret_cast<uintptr_t>(ret) & (align - 1))
   (/home/penberg/osv/core/mempool.cc: alloc_phys_contiguous_aligned:
   1378)

   [backtrace]
   0x398316 <memory::alloc_phys_contiguous_aligned(unsigned long,
   unsigned long)+214>
   0x3542bb <ahci::port::setup()+283>
   0x3549ae <ahci::port::port(unsigned int, ahci::hba*)+142>
   0x354a5f <ahci::hba::scan()+111>
   0x354d34 <ahci::hba::hba(pci::device&)+148>
   0x354e07 <ahci::hba::probe(hw::hw_device*)+119>
   0x33e65c
   <hw::driver_manager::register_driver(std::function<hw::hw_driver*
   (hw::hw_device*)>)+188>
   0x33c8c3 <hw::device_manager::for_each_device(std::function<void
   (hw::hw_device*)>)+51>
   0x33e3de <hw::driver_manager::load_all()+78>
   0x20edf5 <do_main_thread(void*)+629>
   0x3ff0a5 <sync+69>
   0x3a3eaa <thread_main_c+26>
   0x361585 <thread_main+7>

Signed-off-by: default avatarAsias He <asias@cloudius-systems.com>
Signed-off-by: default avatarAvi Kivity <avi@cloudius-systems.com>
parent 2e7bb5c6
No related branches found
No related tags found
No related merge requests found
...@@ -97,21 +97,24 @@ void port::reset() ...@@ -97,21 +97,24 @@ void port::reset()
void port::setup() void port::setup()
{ {
// Setup Command List and Received FIS Structure // Setup Command List and Received FIS Structure
// sz = 32 * 32 = 1024
auto sz = sizeof(*_cmd_list) * 32; auto sz = sizeof(*_cmd_list) * 32;
_cmd_list = reinterpret_cast<struct cmd_list *>( _cmd_list = reinterpret_cast<struct cmd_list *>(
memory::alloc_phys_contiguous_aligned(sz, 1024)); memory::alloc_phys_contiguous_aligned(sz, sz));
_cmd_list_pa = mmu::virt_to_phys(_cmd_list); _cmd_list_pa = mmu::virt_to_phys(_cmd_list);
memset(_cmd_list, 0, sz); memset(_cmd_list, 0, sz);
// sz = 256 * 32 = 8192, cmd_table need to be aligned to 128 bytes
sz = sizeof(*_cmd_table) * 32; sz = sizeof(*_cmd_table) * 32;
_cmd_table = reinterpret_cast<struct cmd_table *>( _cmd_table = reinterpret_cast<struct cmd_table *>(
memory::alloc_phys_contiguous_aligned(sz, 1024)); memory::alloc_phys_contiguous_aligned(sz, 128));
_cmd_table_pa = mmu::virt_to_phys(_cmd_table); _cmd_table_pa = mmu::virt_to_phys(_cmd_table);
memset(_cmd_table, 0, sz); memset(_cmd_table, 0, sz);
// size = 256 * 1 = 256
sz = sizeof(*_recv_fis) * 1; sz = sizeof(*_recv_fis) * 1;
_recv_fis = reinterpret_cast<struct recv_fis *>( _recv_fis = reinterpret_cast<struct recv_fis *>(
memory::alloc_phys_contiguous_aligned(sz, 1024)); memory::alloc_phys_contiguous_aligned(sz, sz));
_recv_fis_pa = mmu::virt_to_phys(_recv_fis); _recv_fis_pa = mmu::virt_to_phys(_recv_fis);
memset(_recv_fis, 0, sz); memset(_recv_fis, 0, sz);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment