mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:27:35 +00:00
Kernel: Tell compiler about invisible calls
This makes the Kernel build cleanly with -Wmissing-declarations.
This commit is contained in:
parent
8a41ce5cc7
commit
936d5dcc01
3 changed files with 47 additions and 28 deletions
|
@ -29,8 +29,9 @@
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/Arch/i386/CPU.h>
|
#include <Kernel/Arch/i386/CPU.h>
|
||||||
#include <Kernel/Arch/i386/ProcessorInfo.h>
|
|
||||||
#include <Kernel/Arch/i386/ISRStubs.h>
|
#include <Kernel/Arch/i386/ISRStubs.h>
|
||||||
|
#include <Kernel/Arch/i386/ProcessorInfo.h>
|
||||||
|
#include <Kernel/IO.h>
|
||||||
#include <Kernel/Interrupts/APIC.h>
|
#include <Kernel/Interrupts/APIC.h>
|
||||||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||||
#include <Kernel/Interrupts/IRQHandler.h>
|
#include <Kernel/Interrupts/IRQHandler.h>
|
||||||
|
@ -44,7 +45,6 @@
|
||||||
#include <Kernel/Thread.h>
|
#include <Kernel/Thread.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
#include <Kernel/VM/PageDirectory.h>
|
#include <Kernel/VM/PageDirectory.h>
|
||||||
#include <Kernel/IO.h>
|
|
||||||
#include <LibC/mallocdefs.h>
|
#include <LibC/mallocdefs.h>
|
||||||
|
|
||||||
//#define PAGE_FAULT_DEBUG
|
//#define PAGE_FAULT_DEBUG
|
||||||
|
@ -58,6 +58,13 @@ static Descriptor s_idt[256];
|
||||||
|
|
||||||
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
|
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
|
||||||
|
|
||||||
|
// The compiler can't see the calls to these functions inside assembly.
|
||||||
|
// Declare them, to avoid dead code warnings.
|
||||||
|
extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread);
|
||||||
|
extern "C" void context_first_init(Thread* from_thread, Thread* to_thread, TrapFrame* trap);
|
||||||
|
extern "C" u32 do_init_context(Thread* thread, u32 flags);
|
||||||
|
extern "C" void pre_init_finished(void);
|
||||||
|
extern "C" void post_init_finished(void);
|
||||||
extern "C" void handle_interrupt(TrapFrame*);
|
extern "C" void handle_interrupt(TrapFrame*);
|
||||||
|
|
||||||
#define EH_ENTRY(ec, title) \
|
#define EH_ENTRY(ec, title) \
|
||||||
|
@ -337,7 +344,7 @@ void breakpoint_handler(TrapFrame* trap)
|
||||||
asm("movl %%cr4, %%eax" \
|
asm("movl %%cr4, %%eax" \
|
||||||
: "=a"(cr4)); \
|
: "=a"(cr4)); \
|
||||||
klog() << "CR0=" << String::format("%x", cr0) << " CR2=" << String::format("%x", cr2) << " CR3=" << String::format("%x", cr3) << " CR4=" << String::format("%x", cr4); \
|
klog() << "CR0=" << String::format("%x", cr0) << " CR2=" << String::format("%x", cr2) << " CR3=" << String::format("%x", cr3) << " CR4=" << String::format("%x", cr4); \
|
||||||
Processor::halt(); \
|
Processor::halt(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
EH(2, "Unknown error")
|
EH(2, "Unknown error")
|
||||||
|
@ -917,14 +924,14 @@ String Processor::features_string() const
|
||||||
};
|
};
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) {
|
for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) {
|
||||||
if ((static_cast<u32>(m_features) & flag) != 0) {
|
if ((static_cast<u32>(m_features) & flag) != 0) {
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
auto str = feature_to_str(static_cast<CPUFeature>(flag));
|
auto str = feature_to_str(static_cast<CPUFeature>(flag));
|
||||||
builder.append(str, strlen(str));
|
builder.append(str, strlen(str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@ -998,7 +1005,7 @@ void Processor::write_raw_gdt_entry(u16 selector, u32 low, u32 high)
|
||||||
{
|
{
|
||||||
u16 i = (selector & 0xfffc) >> 3;
|
u16 i = (selector & 0xfffc) >> 3;
|
||||||
u32 prev_gdt_length = m_gdt_length;
|
u32 prev_gdt_length = m_gdt_length;
|
||||||
|
|
||||||
if (i > m_gdt_length) {
|
if (i > m_gdt_length) {
|
||||||
m_gdt_length = i + 1;
|
m_gdt_length = i + 1;
|
||||||
ASSERT(m_gdt_length <= sizeof(m_gdt) / sizeof(m_gdt[0]));
|
ASSERT(m_gdt_length <= sizeof(m_gdt) / sizeof(m_gdt[0]));
|
||||||
|
@ -1174,11 +1181,11 @@ extern "C" void context_first_init(Thread* from_thread, Thread* to_thread, TrapF
|
||||||
(void)from_thread;
|
(void)from_thread;
|
||||||
(void)to_thread;
|
(void)to_thread;
|
||||||
(void)trap;
|
(void)trap;
|
||||||
|
|
||||||
#ifdef CONTEXT_SWITCH_DEBUG
|
#ifdef CONTEXT_SWITCH_DEBUG
|
||||||
dbg() << "switch_context <-- from " << VirtualAddress(from_thread) << " " << *from_thread << " to " << VirtualAddress(to_thread) << " " << *to_thread << " (context_first_init)";
|
dbg() << "switch_context <-- from " << VirtualAddress(from_thread) << " " << *from_thread << " to " << VirtualAddress(to_thread) << " " << *to_thread << " (context_first_init)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT(to_thread == Thread::current());
|
ASSERT(to_thread == Thread::current());
|
||||||
|
|
||||||
Scheduler::enter_current(*from_thread);
|
Scheduler::enter_current(*from_thread);
|
||||||
|
@ -1229,7 +1236,7 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
|
||||||
|
|
||||||
auto& tss = thread.tss();
|
auto& tss = thread.tss();
|
||||||
bool return_to_user = (tss.cs & 3) != 0;
|
bool return_to_user = (tss.cs & 3) != 0;
|
||||||
|
|
||||||
// make room for an interrupt frame
|
// make room for an interrupt frame
|
||||||
if (!return_to_user) {
|
if (!return_to_user) {
|
||||||
// userspace_esp and userspace_ss are not popped off by iret
|
// userspace_esp and userspace_ss are not popped off by iret
|
||||||
|
@ -1300,7 +1307,6 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
|
||||||
return stack_top;
|
return stack_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" u32 do_init_context(Thread* thread, u32 flags)
|
extern "C" u32 do_init_context(Thread* thread, u32 flags)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
|
@ -1367,7 +1373,7 @@ extern "C" void post_init_finished(void)
|
||||||
void Processor::initialize_context_switching(Thread& initial_thread)
|
void Processor::initialize_context_switching(Thread& initial_thread)
|
||||||
{
|
{
|
||||||
ASSERT(initial_thread.process().is_ring0());
|
ASSERT(initial_thread.process().is_ring0());
|
||||||
|
|
||||||
auto& tss = initial_thread.tss();
|
auto& tss = initial_thread.tss();
|
||||||
m_tss = tss;
|
m_tss = tss;
|
||||||
m_tss.esp0 = tss.esp0;
|
m_tss.esp0 = tss.esp0;
|
||||||
|
@ -1375,9 +1381,9 @@ void Processor::initialize_context_switching(Thread& initial_thread)
|
||||||
// user mode needs to be able to switch to kernel mode:
|
// user mode needs to be able to switch to kernel mode:
|
||||||
m_tss.cs = m_tss.ds = m_tss.es = m_tss.gs = m_tss.ss = GDT_SELECTOR_CODE0 | 3;
|
m_tss.cs = m_tss.ds = m_tss.es = m_tss.gs = m_tss.ss = GDT_SELECTOR_CODE0 | 3;
|
||||||
m_tss.fs = GDT_SELECTOR_PROC | 3;
|
m_tss.fs = GDT_SELECTOR_PROC | 3;
|
||||||
|
|
||||||
m_scheduler_initialized = true;
|
m_scheduler_initialized = true;
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"movl %[new_esp], %%esp \n" // swich to new stack
|
"movl %[new_esp], %%esp \n" // swich to new stack
|
||||||
"pushl %[from_to_thread] \n" // to_thread
|
"pushl %[from_to_thread] \n" // to_thread
|
||||||
|
@ -1508,7 +1514,7 @@ void Processor::smp_enable()
|
||||||
for (size_t k = 0; k < msg_entries_cnt; k++)
|
for (size_t k = 0; k < msg_entries_cnt; k++)
|
||||||
msg_entries[msg_entry_i + k].msg = &msg;
|
msg_entries[msg_entry_i + k].msg = &msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_store(&s_message_pool, &msgs[0], AK::MemoryOrder::memory_order_release);
|
atomic_store(&s_message_pool, &msgs[0], AK::MemoryOrder::memory_order_release);
|
||||||
|
|
||||||
// Start sending IPI messages
|
// Start sending IPI messages
|
||||||
|
@ -1646,7 +1652,7 @@ void Processor::smp_broadcast_message(ProcessorMessage& msg, bool async)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Processor::smp_broadcast(void(*callback)(void*), void* data, void(*free_data)(void*), bool async)
|
void Processor::smp_broadcast(void (*callback)(void*), void* data, void (*free_data)(void*), bool async)
|
||||||
{
|
{
|
||||||
auto& msg = smp_get_from_pool();
|
auto& msg = smp_get_from_pool();
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
msg.type = ProcessorMessage::CallbackWithData;
|
||||||
|
@ -1656,7 +1662,7 @@ void Processor::smp_broadcast(void(*callback)(void*), void* data, void(*free_dat
|
||||||
smp_broadcast_message(msg, async);
|
smp_broadcast_message(msg, async);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Processor::smp_broadcast(void(*callback)(), bool async)
|
void Processor::smp_broadcast(void (*callback)(), bool async)
|
||||||
{
|
{
|
||||||
auto& msg = smp_get_from_pool();
|
auto& msg = smp_get_from_pool();
|
||||||
msg.type = ProcessorMessage::CallbackWithData;
|
msg.type = ProcessorMessage::CallbackWithData;
|
||||||
|
|
|
@ -282,11 +282,6 @@ char* strstr(const char* haystack, const char* needle)
|
||||||
return const_cast<char*>(haystack);
|
return const_cast<char*>(haystack);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void __cxa_pure_virtual()
|
|
||||||
{
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* realloc(void* p, size_t s)
|
void* realloc(void* p, size_t s)
|
||||||
{
|
{
|
||||||
return krealloc(p, s);
|
return krealloc(p, s);
|
||||||
|
@ -297,6 +292,13 @@ void free(void* p)
|
||||||
return kfree(p);
|
return kfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Functions that are automatically called by the C++ compiler.
|
||||||
|
// Declare them first, to tell the silly compiler that they are indeed being used.
|
||||||
|
[[noreturn]] void __stack_chk_fail();
|
||||||
|
[[noreturn]] void __stack_chk_fail_local();
|
||||||
|
extern "C" int __cxa_atexit(void (*)(void*), void*, void*);
|
||||||
|
[[noreturn]] void __cxa_pure_virtual();
|
||||||
|
|
||||||
[[noreturn]] void __stack_chk_fail()
|
[[noreturn]] void __stack_chk_fail()
|
||||||
{
|
{
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
@ -312,4 +314,9 @@ extern "C" int __cxa_atexit(void (*)(void*), void*, void*)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[noreturn]] void __cxa_pure_virtual()
|
||||||
|
{
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,12 @@ namespace Kernel {
|
||||||
[[noreturn]] static void init_stage2();
|
[[noreturn]] static void init_stage2();
|
||||||
static void setup_serial_debug();
|
static void setup_serial_debug();
|
||||||
|
|
||||||
|
// boot.S expects these functions precisely this this. We declare them here
|
||||||
|
// to ensure the signatures don't accidentally change.
|
||||||
|
extern "C" void init_finished(u32 cpu);
|
||||||
|
extern "C" [[noreturn]] void init_ap(u32 cpu, Processor* processor_info);
|
||||||
|
extern "C" [[noreturn]] void init();
|
||||||
|
|
||||||
VirtualConsole* tty0;
|
VirtualConsole* tty0;
|
||||||
|
|
||||||
static Processor s_bsp_processor; // global but let's keep it "private"
|
static Processor s_bsp_processor; // global but let's keep it "private"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue