diff --git a/src/boot/main.cpp b/src/boot/main.cpp index ca88353..df04539 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -176,9 +177,23 @@ efi_main(uefi::handle image, uefi::system_table *st) bootproto::entrypoint kentry = load_resources(args, screen, image, pager, bs); + bootproto::module *acpi_mod = + g_alloc.allocate_module(sizeof(bootproto::acpi)); + acpi_mod->type = bootproto::module_type::acpi; + bootproto::acpi *acpi = acpi_mod->data(); + acpi->root = args->acpi_table; + pager.update_kernel_args(args); memory::efi_mem_map map = uefi_exit(args, image, st->boot_services); + for (size_t i = 0; i < args->mem_map.count; ++i) { + bootproto::mem_entry &e = args->mem_map.pointer[i]; + if (e.type == bootproto::mem_type::acpi) { + acpi->region = util::buffer::from(e.start, e.pages * memory::page_size); + break; + } + } + args->allocations = allocs; args->init_modules = reinterpret_cast(modules); diff --git a/src/kernel/acpi_tables.h b/src/include/arch/acpi/tables.h similarity index 70% rename from src/kernel/acpi_tables.h rename to src/include/arch/acpi/tables.h index bb98db3..d7bf536 100644 --- a/src/kernel/acpi_tables.h +++ b/src/include/arch/acpi/tables.h @@ -6,7 +6,9 @@ #include #include // for byteswap32 -struct acpi_table_header +namespace acpi { + +struct table_header { uint32_t type; uint32_t length; @@ -18,24 +20,26 @@ struct acpi_table_header uint32_t creator_id; uint32_t creator_revision; - bool validate(uint32_t expected_type = 0) const; + bool validate() const { return util::checksum(this, length) == 0; } } __attribute__ ((packed)); + #define TABLE_HEADER(signature) \ static constexpr uint32_t type_id = util::byteswap32(signature); \ - acpi_table_header header; - + table_header header; template -bool acpi_validate(const T *t) { return t->header.validate(T::type_id); } +bool validate(const T *t) { + return t->header.validate(T::type_id); +} template -size_t acpi_table_entries(const T *t, size_t size) -{ +size_t table_entries(const T *t, size_t size) { return (t->header.length - sizeof(T)) / size; } -enum class acpi_gas_type : uint8_t + +enum class gas_type : uint8_t { system_memory, system_io, @@ -46,9 +50,9 @@ enum class acpi_gas_type : uint8_t functional_fixed = 0x7f }; -struct acpi_gas +struct gas { - acpi_gas_type type; + gas_type type; uint8_t reg_bits; uint8_t reg_offset; @@ -58,7 +62,7 @@ struct acpi_gas } __attribute__ ((packed)); -enum class acpi_fadt_flags : uint32_t +enum class fadt_flags : uint32_t { wbinvd = 0x00000001, wbinvd_flush = 0x00000002, @@ -83,9 +87,9 @@ enum class acpi_fadt_flags : uint32_t hw_reduced_acpi = 0x00100000, low_pwr_s0_idle = 0x00200000 }; -is_bitfield(acpi_fadt_flags); +is_bitfield(fadt_flags); -struct acpi_fadt +struct fadt { TABLE_HEADER('FACP'); @@ -130,9 +134,9 @@ struct acpi_fadt uint16_t iapc_boot_arch; uint8_t reserved1; - acpi_fadt_flags flags; + fadt_flags flags; - acpi_gas reset_reg; + gas reset_reg; uint8_t reset_value; uint16_t arm_boot_arch; @@ -142,28 +146,28 @@ struct acpi_fadt uint64_t x_facs; uint64_t x_dsdt; - acpi_gas x_pm1a_event_block; - acpi_gas x_pm1b_event_block; - acpi_gas x_pm1a_control_block; - acpi_gas x_pm1b_control_block; - acpi_gas x_pm2_control_block; - acpi_gas x_pm_timer_block; - acpi_gas x_gpe0_block; - acpi_gas x_gpe1_block; + gas x_pm1a_event_block; + gas x_pm1b_event_block; + gas x_pm1a_control_block; + gas x_pm1b_control_block; + gas x_pm2_control_block; + gas x_pm_timer_block; + gas x_gpe0_block; + gas x_gpe1_block; - acpi_gas sleep_control_reg; - acpi_gas sleep_status_reg; + gas sleep_control_reg; + gas sleep_status_reg; uint64_t hypervisor_vendor_id; } __attribute__ ((packed)); -struct acpi_xsdt +struct xsdt { TABLE_HEADER('XSDT'); - acpi_table_header *headers[0]; + table_header *headers[0]; } __attribute__ ((packed)); -struct acpi_apic +struct apic { TABLE_HEADER('APIC'); uint32_t local_address; @@ -171,7 +175,7 @@ struct acpi_apic uint8_t controller_data[0]; } __attribute__ ((packed)); -struct acpi_mcfg_entry +struct mcfg_entry { uint64_t base; uint16_t group; @@ -180,24 +184,24 @@ struct acpi_mcfg_entry uint32_t reserved; } __attribute__ ((packed)); -struct acpi_mcfg +struct mcfg { TABLE_HEADER('MCFG'); uint64_t reserved; - acpi_mcfg_entry entries[0]; + mcfg_entry entries[0]; } __attribute__ ((packed)); -struct acpi_hpet +struct hpet { TABLE_HEADER('HPET'); uint32_t hardware_id; - acpi_gas base_address; + gas base_address; uint8_t index; uint16_t periodic_min; uint8_t attributes; } __attribute__ ((packed)); -struct acpi_bgrt +struct bgrt { TABLE_HEADER('BGRT'); uint16_t version; @@ -208,3 +212,35 @@ struct acpi_bgrt uint32_t offset_y; } __attribute__ ((packed)); +struct rsdp1 +{ + char signature[8]; + uint8_t checksum; + char oem_id[6]; + uint8_t revision; + uint32_t rsdt_address; +} __attribute__ ((packed)); + +struct rsdp2 +{ + char signature[8]; + uint8_t checksum10; + char oem_id[6]; + uint8_t revision; + uint32_t rsdt_address; + + uint32_t length; + table_header *xsdt_address; + uint8_t checksum20; + uint8_t reserved[3]; +} __attribute__ ((packed)); + +template static const T * +check_get_table(const table_header *header) +{ + if (!header || header->type != T::type_id) + return nullptr; + return reinterpret_cast(header); +} + +} // namespace acpi diff --git a/src/kernel/device_manager.cpp b/src/kernel/device_manager.cpp index 930b20f..fce472f 100644 --- a/src/kernel/device_manager.cpp +++ b/src/kernel/device_manager.cpp @@ -3,9 +3,9 @@ #include #include // for checksum #include +#include #include "assert.h" -#include "acpi_tables.h" #include "apic.h" #include "clock.h" #include "device_manager.h" @@ -21,37 +21,6 @@ static const char expected_signature[] = "RSD PTR "; device_manager device_manager::s_instance; -struct acpi1_rsdp -{ - char signature[8]; - uint8_t checksum; - char oem_id[6]; - uint8_t revision; - uint32_t rsdt_address; -} __attribute__ ((packed)); - -struct acpi2_rsdp -{ - char signature[8]; - uint8_t checksum10; - char oem_id[6]; - uint8_t revision; - uint32_t rsdt_address; - - uint32_t length; - acpi_table_header *xsdt_address; - uint8_t checksum20; - uint8_t reserved[3]; -} __attribute__ ((packed)); - -bool -acpi_table_header::validate(uint32_t expected_type) const -{ - if (util::checksum(this, length) != 0) return false; - return !expected_type || (expected_type == type); -} - - device_manager::device_manager() : m_lapic_base(0) { @@ -63,37 +32,32 @@ device_manager::device_manager() : m_irqs[2] = {ignore_event, 0}; } -template static const T * -check_get_table(const acpi_table_header *header) -{ - kassert(header && header->validate(T::type_id), "Invalid ACPI table."); - return reinterpret_cast(header); -} - void device_manager::parse_acpi(const void *root_table) { kassert(root_table != 0, "ACPI root table pointer is null."); - const acpi1_rsdp *acpi1 = mem::to_virtual( - reinterpret_cast(root_table)); + const acpi::rsdp1 *acpi1 = mem::to_virtual( + reinterpret_cast(root_table)); for (int i = 0; i < sizeof(acpi1->signature); ++i) kassert(acpi1->signature[i] == expected_signature[i], "ACPI RSDP table signature mismatch"); - uint8_t sum = util::checksum(acpi1, sizeof(acpi1_rsdp), 0); + uint8_t sum = util::checksum(acpi1, sizeof(acpi::rsdp1), 0); kassert(sum == 0, "ACPI 1.0 RSDP checksum mismatch."); kassert(acpi1->revision > 1, "ACPI 1.0 not supported."); - const acpi2_rsdp *acpi2 = - reinterpret_cast(acpi1); + const acpi::rsdp2 *acpi2 = + reinterpret_cast(acpi1); - sum = util::checksum(acpi2, sizeof(acpi2_rsdp), sizeof(acpi1_rsdp)); + sum = util::checksum(acpi2, sizeof(acpi::rsdp2), sizeof(acpi::rsdp1)); kassert(sum == 0, "ACPI 2.0 RSDP checksum mismatch."); - load_xsdt(mem::to_virtual(acpi2->xsdt_address)); + const acpi::table_header *xsdt = mem::to_virtual(acpi2->xsdt_address); + kassert(xsdt->validate(), "Bad XSDT table"); + load_xsdt(xsdt); } const device_manager::apic_nmi * @@ -129,53 +93,50 @@ put_sig(char *into, uint32_t type) } void -device_manager::load_xsdt(const acpi_table_header *header) +device_manager::load_xsdt(const acpi::table_header *header) { - const auto *xsdt = check_get_table(header); + const auto *xsdt = acpi::check_get_table(header); char sig[5] = {0,0,0,0,0}; log::info(logs::device, "ACPI 2.0+ tables loading"); put_sig(sig, xsdt->header.type); - log::verbose(logs::device, " Found table %s", sig); + log::verbose(logs::device, " Loading table %s", sig); - size_t num_tables = acpi_table_entries(xsdt, sizeof(void*)); + size_t num_tables = acpi::table_entries(xsdt, sizeof(void*)); for (size_t i = 0; i < num_tables; ++i) { - const acpi_table_header *header = + const acpi::table_header *header = mem::to_virtual(xsdt->headers[i]); - put_sig(sig, header->type); - log::verbose(logs::device, " Found table %s", sig); - kassert(header->validate(), "Table failed validation."); + put_sig(sig, header->type); switch (header->type) { - case acpi_apic::type_id: + case acpi::apic::type_id: + log::verbose(logs::device, " Loading table %s", sig); load_apic(header); break; - case acpi_mcfg::type_id: - load_mcfg(header); - break; - - case acpi_hpet::type_id: + case acpi::hpet::type_id: + log::verbose(logs::device, " Loading table %s", sig); load_hpet(header); break; default: + log::verbose(logs::device, " Skipping table %s", sig); break; } } } void -device_manager::load_apic(const acpi_table_header *header) +device_manager::load_apic(const acpi::table_header *header) { - const auto *apic = check_get_table(header); + const auto *apic = acpi::check_get_table(header); m_lapic_base = apic->local_address; - size_t count = acpi_table_entries(apic, 1); + size_t count = acpi::table_entries(apic, 1); uint8_t const *p = apic->controller_data; uint8_t const *end = p + count; @@ -265,33 +226,9 @@ device_manager::load_apic(const acpi_table_header *header) } void -device_manager::load_mcfg(const acpi_table_header *header) +device_manager::load_hpet(const acpi::table_header *header) { - const auto *mcfg = check_get_table(header); - - size_t count = acpi_table_entries(mcfg, sizeof(acpi_mcfg_entry)); - m_pci.set_size(count); - m_devices.set_capacity(16); - - for (unsigned i = 0; i < count; ++i) { - const acpi_mcfg_entry &mcfge = mcfg->entries[i]; - - m_pci[i].group = mcfge.group; - m_pci[i].bus_start = mcfge.bus_start; - m_pci[i].bus_end = mcfge.bus_end; - m_pci[i].base = mem::to_virtual(mcfge.base); - - log::spam(logs::device, " Found MCFG entry: base %lx group %d bus %d-%d", - mcfge.base, mcfge.group, mcfge.bus_start, mcfge.bus_end); - } - - probe_pci(); -} - -void -device_manager::load_hpet(const acpi_table_header *header) -{ - const auto *hpet = check_get_table(header); + const auto *hpet = acpi::check_get_table(header); log::verbose(logs::device, " Found HPET device #%3d: base %016lx pmin %d attr %02x", hpet->index, hpet->base_address.address, hpet->periodic_min, hpet->attributes); @@ -311,28 +248,6 @@ device_manager::load_hpet(const acpi_table_header *header) reinterpret_cast(hpet->base_address.address + mem::linear_offset)); } -void -device_manager::probe_pci() -{ - for (auto &pci : m_pci) { - log::verbose(logs::device, "Probing PCI group at base %016lx", pci.base); - - for (int bus = pci.bus_start; bus <= pci.bus_end; ++bus) { - for (int dev = 0; dev < 32; ++dev) { - if (!pci.has_device(bus, dev, 0)) continue; - - auto &d0 = m_devices.emplace(pci, bus, dev, 0); - if (!d0.multi()) continue; - - for (int i = 1; i < 8; ++i) { - if (pci.has_device(bus, dev, i)) - m_devices.emplace(pci, bus, dev, i); - } - } - } - } -} - static uint64_t tsc_clock_source(void*) { @@ -366,7 +281,7 @@ device_manager::init_drivers() // becomes the singleton master_clock = new clock(h.rate(), hpet_clock_source, &h); - log::info(logs::clock, "Created master clock using HPET 0: Rate %d", h.rate()); + log::info(logs::timer, "Created master clock using HPET 0: Rate %d", h.rate()); } else { //TODO: Other clocks, APIC clock? master_clock = new clock(5000, tsc_clock_source, nullptr); @@ -410,10 +325,10 @@ device_manager::unbind_irqs(obj::event *target) } } +/* bool device_manager::allocate_msi(const char *name, pci_device &device, irq_callback cb, void *data) { - /* // TODO: find gaps to fill uint8_t irq = m_irqs.count(); isr vector = isr::irq00 + irq; @@ -424,12 +339,6 @@ device_manager::allocate_msi(const char *name, pci_device &device, irq_callback device.write_msi_regs( 0xFEE00000, static_cast(vector)); - */ return true; } - -void -device_manager::register_block_device(block_device *blockdev) -{ - m_blockdevs.append(blockdev); -} +*/ diff --git a/src/kernel/device_manager.h b/src/kernel/device_manager.h index b960a52..6646a6e 100644 --- a/src/kernel/device_manager.h +++ b/src/kernel/device_manager.h @@ -6,11 +6,13 @@ #include "apic.h" #include "hpet.h" -#include "pci.h" -struct acpi_table_header; class block_device; +namespace acpi { + struct table_header; +} + namespace obj { class event; } @@ -53,18 +55,6 @@ public: /// \arg target The endpoint to remove void unbind_irqs(obj::event *target); - /// Allocate an MSI IRQ for a device - /// \arg name Name of the interrupt, for display to user - /// \arg device Device this MSI is being allocated for - /// \arg cb Callback to call when the interrupt is received - /// \arg data Data to pass to the callback - /// \returns True if an interrupt was allocated successfully - bool allocate_msi( - const char *name, - pci_device &device, - irq_callback cb, - void *data); - /// Dispatch an IRQ interrupt /// \arg irq The irq number of the interrupt /// \returns True if the interrupt was handled @@ -103,23 +93,6 @@ public: /// configuration, or null if no configuration was provided const irq_override * get_irq_override(uint8_t irq) const; - /// Register the existance of a block device. - /// \arg blockdev Pointer to the block device - void register_block_device(block_device *blockdev); - - /// Get the number of block devices in the system - /// \returns A count of devices - inline unsigned get_num_block_devices() const { return m_blockdevs.count(); } - - /// Get a block device - /// \arg i Index of the device to get - /// \returns A pointer to the requested device, or nullptr - inline block_device * get_block_device(unsigned i) - { - return i < m_blockdevs.count() ? - m_blockdevs[i] : nullptr; - } - /// Get an HPET device /// \arg i Index of the device to get /// \returns A pointer to the requested device, or nullptr @@ -132,23 +105,15 @@ public: private: /// Parse the ACPI XSDT and load relevant sub-tables. /// \arg xsdt Pointer to the XSDT from the firmware - void load_xsdt(const acpi_table_header *xsdt); + void load_xsdt(const acpi::table_header *xsdt); /// Parse the ACPI MADT and initialize APICs from it. /// \arg apic Pointer to the MADT from the XSDT - void load_apic(const acpi_table_header *apic); - - /// Parse the ACPI MCFG and initialize PCIe from it. - /// \arg mcfg Pointer to the MCFG from the XSDT - void load_mcfg(const acpi_table_header *mcfg); + void load_apic(const acpi::table_header *apic); /// Parse the ACPI HPET and initialize an HPET from it. /// \arg hpet Pointer to the HPET from the XSDT - void load_hpet(const acpi_table_header *hpet); - - /// Probe the PCIe busses and add found devices to our - /// device list. The device list is destroyed and rebuilt. - void probe_pci(); + void load_hpet(const acpi::table_header *hpet); /// Handle a bad IRQ. Called when an interrupt is dispatched /// that has no callback. @@ -162,9 +127,6 @@ private: util::vector m_nmis; util::vector m_overrides; - util::vector m_pci; - util::vector m_devices; - struct irq_binding { obj::event *target = nullptr; @@ -172,8 +134,6 @@ private: }; util::vector m_irqs; - util::vector m_blockdevs; - static device_manager s_instance; device_manager(const device_manager &) = delete; diff --git a/src/kernel/kernel.module b/src/kernel/kernel.module index 0a013a3..c6c5c7f 100644 --- a/src/kernel/kernel.module +++ b/src/kernel/kernel.module @@ -43,7 +43,6 @@ kernel = module("kernel", "objects/vm_area.cpp", "page_table.cpp", "page_tree.cpp", - "pci.cpp", "scheduler.cpp", "smp.cpp", "smp.s", diff --git a/src/libraries/bootproto/bootproto.module b/src/libraries/bootproto/bootproto.module index 1869fb5..6484612 100644 --- a/src/libraries/bootproto/bootproto.module +++ b/src/libraries/bootproto/bootproto.module @@ -3,6 +3,7 @@ bp = module("bootproto", kind = "lib", public_headers = [ + "bootproto/acpi.h", "bootproto/bootconfig.h", "bootproto/devices/framebuffer.h", "bootproto/init.h", diff --git a/src/libraries/bootproto/bootproto/acpi.h b/src/libraries/bootproto/bootproto/acpi.h new file mode 100644 index 0000000..df9feca --- /dev/null +++ b/src/libraries/bootproto/bootproto/acpi.h @@ -0,0 +1,15 @@ +#pragma once +/// \file bootproto/acpi.h +/// Data structures for passing ACPI tables to the init server + +#include + +namespace bootproto { + +struct acpi +{ + util::const_buffer region; + void const *root; +}; + +} // namespace bootproto diff --git a/src/libraries/bootproto/bootproto/init.h b/src/libraries/bootproto/bootproto/init.h index 89121dd..bbe8004 100644 --- a/src/libraries/bootproto/bootproto/init.h +++ b/src/libraries/bootproto/bootproto/init.h @@ -10,7 +10,7 @@ namespace bootproto { -enum class module_type : uint8_t { none, initrd, device, }; +enum class module_type : uint8_t { none, initrd, device, acpi }; struct module { diff --git a/src/user/srv.init/acpi.cpp b/src/user/srv.init/acpi.cpp new file mode 100644 index 0000000..4f485b8 --- /dev/null +++ b/src/user/srv.init/acpi.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include + +#include "acpi.h" +#include "loader.h" +#include "pci.h" + +inline constexpr size_t bus_mmio_size = 0x1000'0000; +inline constexpr j6_vm_flags mmio_flags = (j6_vm_flags)(j6_vm_flag_write | j6_vm_flag_mmio); + +void +probe_pci(j6_handle_t sys, pci_group &pci) +{ + j6::syslog("Probing PCI group at base %016lx", pci.base); + map_phys(sys, pci.base, bus_mmio_size, mmio_flags); + + for (unsigned b = pci.bus_start; b <= pci.bus_end; ++b) { + uint8_t bus = static_cast(b); + + for (uint8_t dev = 0; dev < 32; ++dev) { + if (!pci.has_device(bus, dev, 0)) continue; + + pci_device d0 {pci, bus, dev, 0}; + if (!d0.multi()) continue; + + for (uint8_t i = 1; i < 8; ++i) { + if (pci.has_device(bus, dev, i)) + pci_device dn {pci, bus, dev, i}; + } + } + } +} + +void +load_mcfg(j6_handle_t sys, const acpi::table_header *header) +{ + const auto *mcfg = acpi::check_get_table(header); + + size_t count = acpi::table_entries(mcfg, sizeof(acpi::mcfg_entry)); + + /* + m_pci.set_size(count); + m_devices.set_capacity(16); + */ + + for (unsigned i = 0; i < count; ++i) { + const acpi::mcfg_entry &mcfge = mcfg->entries[i]; + + pci_group group = { + .group = mcfge.group, + .bus_start = mcfge.bus_start, + .bus_end = mcfge.bus_end, + .base = reinterpret_cast(mcfge.base), + }; + + probe_pci(sys, group); + + j6::syslog(" Found MCFG entry: base %lx group %d bus %d-%d", + mcfge.base, mcfge.group, mcfge.bus_start, mcfge.bus_end); + } + + //probe_pci(); +} + +void +load_acpi(j6_handle_t sys, const bootproto::module *mod) +{ + const bootproto::acpi *info = mod->data(); + const util::const_buffer ®ion = info->region; + + map_phys(sys, region.pointer, region.count); + + const void *root_table = info->root; + if (!root_table) { + j6::syslog("null ACPI root table pointer"); + return; + } + + const acpi::rsdp2 *acpi2 = + reinterpret_cast(root_table); + + const auto *xsdt = + acpi::check_get_table(acpi2->xsdt_address); + + size_t num_tables = acpi::table_entries(xsdt, sizeof(void*)); + for (size_t i = 0; i < num_tables; ++i) { + const acpi::table_header *header = xsdt->headers[i]; + if (!header->validate()) { + j6::syslog("ACPI table at %lx failed validation", header); + continue; + } + + switch (header->type) { + case acpi::mcfg::type_id: + load_mcfg(sys, header); + break; + + default: + break; + } + } +} diff --git a/src/user/srv.init/acpi.h b/src/user/srv.init/acpi.h new file mode 100644 index 0000000..60b9554 --- /dev/null +++ b/src/user/srv.init/acpi.h @@ -0,0 +1,12 @@ +#pragma once +/// \file acpi.h +/// Routines for loading and parsing ACPI tables + +#include +#include + +namespace bootproto { + struct module; +} + +void load_acpi(j6_handle_t sys, const bootproto::module *mod); diff --git a/src/user/srv.init/init.module b/src/user/srv.init/init.module index 75f148e..0a293de 100644 --- a/src/user/srv.init/init.module +++ b/src/user/srv.init/init.module @@ -6,10 +6,12 @@ init = module("srv.init", description = "Init server", ld_script = "init.ld", sources = [ + "acpi.cpp", "j6romfs.cpp", "loader.cpp", "main.cpp", "modules.cpp", + "pci.cpp", "service_locator.cpp", "start.s", ]) diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index a2fd8f4..cb06715 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -19,17 +19,14 @@ constexpr size_t stack_size = 0x10000; constexpr uintptr_t stack_top = 0x80000000000; j6_handle_t -map_phys(j6_handle_t sys, uintptr_t phys, size_t len, uintptr_t addr) +map_phys(j6_handle_t sys, uintptr_t phys, size_t len, j6_vm_flags flags) { j6_handle_t vma = j6_handle_invalid; - j6_status_t res = j6_system_map_phys(sys, &vma, phys, len, 0); + j6_status_t res = j6_system_map_phys(sys, &vma, phys, len, flags); if (res != j6_status_ok) return j6_handle_invalid; - if (!addr) - addr = phys; - - res = j6_vma_map(vma, 0, addr); + res = j6_vma_map(vma, 0, phys); if (res != j6_status_ok) return j6_handle_invalid; diff --git a/src/user/srv.init/loader.h b/src/user/srv.init/loader.h index ce4f3e9..e254192 100644 --- a/src/user/srv.init/loader.h +++ b/src/user/srv.init/loader.h @@ -3,6 +3,7 @@ /// Routines for loading and starting other programs #include +#include #include namespace bootproto { @@ -15,8 +16,8 @@ bool load_program( j6_handle_t sys, j6_handle_t slp, const bootproto::module *arg = nullptr); -j6_handle_t map_phys(j6_handle_t sys, uintptr_t phys, size_t len, uintptr_t addr = 0); +j6_handle_t map_phys(j6_handle_t sys, uintptr_t phys, size_t len, j6_vm_flags flags = j6_vm_flag_none); -inline j6_handle_t map_phys(j6_handle_t sys, const void *phys, size_t len, uintptr_t addr = 0) { - return map_phys(sys, reinterpret_cast(phys), len, addr); +inline j6_handle_t map_phys(j6_handle_t sys, const void *phys, size_t len, j6_vm_flags flags = j6_vm_flag_none) { + return map_phys(sys, reinterpret_cast(phys), len, flags); } diff --git a/src/user/srv.init/main.cpp b/src/user/srv.init/main.cpp index ed20b41..c6b5c70 100644 --- a/src/user/srv.init/main.cpp +++ b/src/user/srv.init/main.cpp @@ -9,9 +9,11 @@ #include #include +#include #include #include +#include "acpi.h" #include "j6romfs.h" #include "loader.h" #include "modules.h" @@ -86,6 +88,7 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar load_modules(modules_addr, sys, 0, mods); module const *initrd_module = nullptr; + module const *acpi_module = nullptr; std::vector devices; for (auto mod : mods) { @@ -94,6 +97,10 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar initrd_module = mod; break; + case module_type::acpi: + acpi_module = mod; + break; + case module_type::device: devices.push_back(mod); break; @@ -105,7 +112,10 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar } if (!initrd_module) - return 1; + return 2; + + if (!acpi_module) + return 3; util::const_buffer initrd_buf = *initrd_module->data(); @@ -120,6 +130,7 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar // have driver_source objects.. j6romfs::fs initrd {initrd_buf}; + load_acpi(sys, acpi_module); const j6romfs::inode *driver_dir = initrd.lookup_inode("/jsix/drivers"); if (!driver_dir) { diff --git a/src/kernel/pci.cpp b/src/user/srv.init/pci.cpp similarity index 80% rename from src/kernel/pci.cpp rename to src/user/srv.init/pci.cpp index c7984c1..b1bdfcf 100644 --- a/src/kernel/pci.cpp +++ b/src/user/srv.init/pci.cpp @@ -1,6 +1,7 @@ -#include "assert.h" -#include "logger.h" -#include "interrupts.h" +#include + +#include + #include "pci.h" struct pci_cap_msi @@ -73,7 +74,6 @@ pci_device::pci_device() : m_subclass(0), m_progif(0), m_revision(0), - m_irq(isr::isrIgnore0), m_header_type(0) { } @@ -81,8 +81,7 @@ pci_device::pci_device() : pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t func) : m_base(group.base_for(bus, device, func)), m_msi(nullptr), - m_bus_addr(bus_addr(bus, device, func)), - m_irq(isr::isrIgnore0) + m_bus_addr(bus_addr(bus, device, func)) { m_vendor = m_base[0] & 0xffff; m_device = (m_base[0] >> 16) & 0xffff; @@ -100,11 +99,11 @@ pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t fu uint16_t *status = command + 1; - log::info(logs::device, "Found PCIe device at %02d:%02d:%d of type %x.%x.%x id %04x:%04x", + j6::syslog("Found PCIe device at %02d:%02d:%d of type %x.%x.%x id %04x:%04x", bus, device, func, m_class, m_subclass, m_progif, m_vendor, m_device); - log::spam(logs::device, " = BAR0 %016lld", get_bar(0)); - log::spam(logs::device, " = BAR1 %016lld", get_bar(1)); + j6::syslog(" = BAR0 %016lld", get_bar(0)); + j6::syslog(" = BAR1 %016lld", get_bar(1)); if (*status & 0x0010) { // Walk the extended capabilities list @@ -112,7 +111,7 @@ pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t fu while (next) { pci_cap *cap = reinterpret_cast(util::offset_pointer(m_base, next)); next = cap->next; - log::verbose(logs::device, " - found PCI cap type %02x", cap->id); + //log::verbose(logs::device, " - found PCI cap type %02x", cap->id); if (cap->id == pci_cap::type::msi) { m_msi = cap; @@ -128,11 +127,10 @@ uint32_t pci_device::get_bar(unsigned i) { if (m_header_type == 0) { - kassert(i < 6, "Requested BAR >5 for PCI device"); - } else if (m_header_type == 1) { - kassert(i < 2, "Requested BAR >1 for PCI bridge"); + assert(i < 6); // Device max BAR is 5 } else { - kassert(0, "Requested BAR for other PCI device type"); + assert(m_header_type == 1); // Only device or bridge + assert(i < 2); // Bridge max BAR is 1 } return m_base[4+i]; @@ -142,11 +140,10 @@ void pci_device::set_bar(unsigned i, uint32_t val) { if (m_header_type == 0) { - kassert(i < 6, "Requested BAR >5 for PCI device"); - } else if (m_header_type == 1) { - kassert(i < 2, "Requested BAR >1 for PCI bridge"); + assert(i < 6); // Device max BAR is 5 } else { - kassert(0, "Requested BAR for other PCI device type"); + assert(m_header_type == 1); // Only device or bridge + assert(i < 2); // Bridge max BAR is 1 } m_base[4+i] = val; @@ -155,7 +152,9 @@ pci_device::set_bar(unsigned i, uint32_t val) void pci_device::write_msi_regs(uintptr_t address, uint16_t data) { - kassert(m_msi, "Tried to write MSI for a device without that cap"); + if (!m_msi) + return; + if (m_msi->id == pci_cap::type::msi) { pci_cap_msi *mcap = reinterpret_cast(m_msi); if (mcap->control & 0x0080) { @@ -172,7 +171,7 @@ pci_device::write_msi_regs(uintptr_t address, uint16_t data) control |= 0x0001; // Enable MSI mcap->control = control; } else { - kassert(0, "MIS-X is NYI"); + assert(0 && "MIS-X is NYI"); } } diff --git a/src/kernel/pci.h b/src/user/srv.init/pci.h similarity index 98% rename from src/kernel/pci.h rename to src/user/srv.init/pci.h index 08d59ec..f81fa11 100644 --- a/src/kernel/pci.h +++ b/src/user/srv.init/pci.h @@ -104,8 +104,6 @@ private: uint8_t m_revision; bool m_multi; - // Might as well cache these to fill out the struct align - isr m_irq; uint8_t m_header_type; };