blob: a6c993bdcfd3bbd9676167cf51e56f4acb755b38 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/lib/machina/arch/x86/e820.h"
#include "garnet/lib/machina/address.h"
static constexpr uint32_t kE820Ram = 1;
static constexpr uint32_t kE820Reserved = 2;
// clang-format off
static constexpr uint64_t kAddr32kb = 0x0000000000008000;
static constexpr uint64_t kAddr64kb = 0x0000000000010000;
static constexpr uint64_t kAddr1mb = 0x0000000000100000;
static constexpr uint64_t kAddr3500mb = 0x00000000e0000000;
static constexpr uint64_t kAddr4000mb = 0x0000000100000000;
// clang-format on
typedef struct e820entry {
uint64_t addr;
uint64_t size;
uint32_t type;
} __PACKED e820entry_t;
namespace machina {
size_t e820_entries(size_t size) {
return (size > kAddr4000mb ? 6 : 5);
}
size_t e820_size(size_t size) {
return e820_entries(size) * sizeof(e820entry_t);
}
zx_status_t create_e820(uintptr_t addr, size_t size, uintptr_t e820_off) {
if (e820_off + e820_size(size) > size)
return ZX_ERR_BUFFER_TOO_SMALL;
e820entry_t* entry = (e820entry_t*)(addr + e820_off);
// 0 to 32kb is reserved.
entry[0].addr = 0;
entry[0].size = kAddr32kb;
entry[0].type = kE820Reserved;
// 32kb to to 64kb is available (for linux's real mode trampoline).
entry[1].addr = kAddr32kb;
entry[1].size = kAddr32kb;
entry[1].type = kE820Ram;
// 64kb to 1mb is reserved.
entry[2].addr = kAddr64kb;
entry[2].size = kAddr1mb - kAddr64kb;
entry[2].type = kE820Reserved;
// 1mb to min(size, 3500mb) is available.
entry[3].addr = kAddr1mb;
entry[3].size = (size < kAddr3500mb ? size : kAddr3500mb) - kAddr1mb;
entry[3].type = kE820Ram;
// 3500mb to 4000mb is reserved.
entry[4].addr = kAddr3500mb;
entry[4].size = kAddr4000mb - kAddr3500mb;
entry[4].type = kE820Reserved;
if (size > kAddr4000mb) {
// If size > 4000mb, then make that region available.
entry[5].addr = kAddr4000mb;
entry[5].size = size - kAddr4000mb;
entry[5].type = kE820Ram;
}
return ZX_OK;
}
} // namespace machina