metal-cos/sys/arm64/machine.c
2024-09-26 04:07:50 +08:00

196 lines
3.5 KiB
C

#include <stdbool.h>
#include <stdint.h>
#include <sys/kconfig.h>
#include <sys/kassert.h>
#include <sys/kmem.h>
#include <sys/mp.h>
#include <sys/irq.h>
#include <sys/spinlock.h>
#include <machine/cpu.h>
#include <machine/trap.h>
#include <machine/pmap.h>
#include <machine/mp.h>
#include <machine/gic.h>
#include <sys/thread.h>
#include <sys/disk.h>
#include <sys/bufcache.h>
#include <sys/vfs.h>
#include <sys/elf64.h>
#include "../dev/console.h"
#include "machine/cpuop.h"
extern void KTime_Init();
extern void KTimer_Init();
extern void RTC_Init();
extern void PCI_Init();
extern void MachineBoot_AddMem();
extern void Loader_LoadInit();
extern void PAlloc_LateInit();
/**
* Machine_SyscallInit --
*
* Configure the model specific registers (MSRs) that specify how to transfer
* control to the operating system when the system call instruction is invoked.
*/
static void
Machine_SyscallInit()
{
kprintf("Initializing Syscall... ");
NOT_IMPLEMENTED();
kprintf("Done!\n");
}
/**
* Machine_EarlyInit --
*
* Initializes early kernel state.
*/
void
Machine_EarlyInit()
{
Spinlock_EarlyInit();
Critical_Init();
Critical_Enter();
WaitChannel_EarlyInit();
Console_Init();
PAlloc_Init();
}
static void
Machine_IdleThread(void *test)
{
while (1) { enable_interrupts(); hlt(); }
}
/**
* Machine_Init --
*
* At this point the assembly startup code has setup temporary processor data
* structures sufficient to execute C code and make it through this
* initialization routine.
*/
void Machine_Init()
{
Machine_EarlyInit();
/*
* Initialize Processor State
*/
if (gic_init() != 0) {
PANIC("gic initialization failed!\n");
}
kprintf("Initialized GIC.\n");
// enable hardware timer
__asm__ volatile (
"mrs x1, CNTFRQ_EL0;"
"msr CNTP_TVAL_EL0, x1;"
"mov x0, #1;"
"msr CNTP_CTL_EL0, x0;"
"msr DAIFClr, #0b1111;"
:
:
: "x0", "x1"
);
while(1) {
hlt();
};
//Machine_SyscallInit();
/*
* Initialize Memory Allocation and Virtual Memory
*/
PAlloc_AddRegion(DMPA2VA(16*1024*1024), 16*1024*1024);
PMap_Init();
XMem_Init();
PAlloc_LateInit();
MachineBoot_AddMem();
/*
* Initialize Time Keeping
*/
KTime_Init();
RTC_Init(); // Finishes initializing KTime
/*
* Initialize Interrupts
*/
IRQ_Init();
// GICv3
Thread_Init();
KTimer_Init(); // Depends on RTC and KTime
/*
* Initialize Additional Processors
*/
MP_Init();
/*
* Initialize Basic Devices
*/
PCI_Init(); // PCI BUS
BufCache_Init();
/*
* Open the primary disk and mount the root file system
*/
Disk *root = Disk_GetByID(0, 0);
if (!root)
Panic("No boot disk!");
VFS_MountRoot(root);
Critical_Exit();
/*
* Create the idle thread
*/
Thread *thr = Thread_KThreadCreate(&Machine_IdleThread, NULL);
if (thr == NULL) {
kprintf("Couldn't create idle thread!\n");
}
Sched_SetRunnable(thr);
/*
* Load the init processor
*/
Loader_LoadInit();
breakpoint();
}
/**
* Machine_InitAP --
*
* Shorter initialization routine for co-processors.
*/
void Machine_InitAP()
{
Critical_Enter();
// Setup CPU state
Trap_InitAP();
PMap_InitAP();
Machine_SyscallInit();
// Setup LAPIC
// Boot processor
MP_InitAP();
Thread_InitAP();
Critical_Exit();
Machine_IdleThread(NULL);
}