pci enumeration
This commit is contained in:
parent
b5ac633a9e
commit
4a7f582881
3
sys/arm64/include/pci.h
Normal file
3
sys/arm64/include/pci.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int PCI_Discover(void);
|
@ -7,6 +7,9 @@
|
||||
#include <sys/mp.h>
|
||||
#include <sys/irq.h>
|
||||
#include <sys/spinlock.h>
|
||||
#include <sys/pci.h>
|
||||
#include <sys/ktime.h>
|
||||
#include <sys/ktimer.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/trap.h>
|
||||
@ -25,10 +28,8 @@
|
||||
#include <machine/mrt.h>
|
||||
#include <machine/pdcache.h>
|
||||
#include <machine/timer.h>
|
||||
#include <machine/pci.h>
|
||||
|
||||
extern void KTime_Init();
|
||||
extern void KTimer_Init();
|
||||
extern void PCI_Init();
|
||||
extern void MachineBoot_AddMem();
|
||||
extern void Loader_LoadInit();
|
||||
extern void PAlloc_LateInit();
|
||||
@ -113,11 +114,6 @@ void Machine_Init()
|
||||
KTimer_Init();
|
||||
enable_interrupts();
|
||||
|
||||
while(1){
|
||||
hlt();
|
||||
}
|
||||
|
||||
// GICv3
|
||||
Thread_Init();
|
||||
|
||||
/*
|
||||
@ -128,9 +124,16 @@ void Machine_Init()
|
||||
/*
|
||||
* Initialize Basic Devices
|
||||
*/
|
||||
int ret;
|
||||
if ((ret = PCI_Discover()) != 0) {
|
||||
Panic("Failed to detect PCIe host controller: %d.\n", ret);
|
||||
}
|
||||
PCI_Init(); // PCI BUS
|
||||
BufCache_Init();
|
||||
|
||||
while(1){
|
||||
hlt();
|
||||
}
|
||||
/*
|
||||
* Open the primary disk and mount the root file system
|
||||
*/
|
||||
|
@ -3,75 +3,93 @@
|
||||
|
||||
#include <sys/kassert.h>
|
||||
#include <sys/pci.h>
|
||||
#include <sys/contrib/libfdt/libfdt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuop.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/pci.h>
|
||||
|
||||
#define PCI_PORT_ADDR 0xCF8
|
||||
#define PCI_PORT_DATABASE 0xCFC
|
||||
static void * pci_conf_space;
|
||||
static UNUSED size_t pci_conf_size;
|
||||
|
||||
static inline uint32_t
|
||||
static inline volatile void *
|
||||
PCIGetAddr(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
|
||||
{
|
||||
ASSERT(bus < 256 && slot < 64 && func < 8 && reg < 256);
|
||||
return (1 << 31) | (bus << 16) | (slot << 11) | (func << 8) | (reg & 0x00fc);
|
||||
return pci_conf_space + ((bus << 20) | (slot << 15) | (func << 12) | (reg & 0xff));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCICfgRead8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
|
||||
|
||||
return 0;
|
||||
volatile uint8_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
return * ret;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PCICfgRead16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE + (reg & 0x2);
|
||||
|
||||
ASSERT((reg & 0x1) == 0);
|
||||
|
||||
return 0;
|
||||
volatile uint16_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
return * ret;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PCICfgRead32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE;
|
||||
|
||||
ASSERT((reg & 0x3) == 0);
|
||||
|
||||
return 0;
|
||||
volatile uint32_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
return * ret;
|
||||
}
|
||||
|
||||
void
|
||||
PCICfgWrite8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
|
||||
UNUSED uint8_t data)
|
||||
PCICfgWrite8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg, uint8_t data)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
|
||||
|
||||
volatile uint8_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
*ret = data;
|
||||
}
|
||||
|
||||
void
|
||||
PCICfgWrite16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
|
||||
UNUSED uint16_t data)
|
||||
uint16_t data)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
|
||||
|
||||
volatile uint16_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
*ret = data;
|
||||
}
|
||||
|
||||
void
|
||||
PCICfgWrite32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
|
||||
UNUSED uint32_t data)
|
||||
uint32_t data)
|
||||
{
|
||||
UNUSED uint32_t addr = PCIGetAddr(bus, slot, func, reg);
|
||||
UNUSED uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
|
||||
|
||||
volatile uint32_t * ret = PCIGetAddr(bus, slot, func, reg);
|
||||
*ret = data;
|
||||
}
|
||||
|
||||
int
|
||||
PCI_Discover(void)
|
||||
{
|
||||
const void * dtb = kbootinfo.dtb_addr;
|
||||
const int offset = fdt_node_offset_by_compatible(dtb, -1, "pci-host-ecam-generic");
|
||||
|
||||
if (offset < 0) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
int lenp;
|
||||
const struct fdt_property * prop = fdt_get_property(dtb, offset, "reg", &lenp);
|
||||
|
||||
if (prop == NULL || lenp != 4 * sizeof(uint32_t)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
const uint32_t * ptr = (const uint32_t *)prop->data;
|
||||
const uint64_t conf_base = fdt32_to_cpu(ptr[1]) | ((uint64_t)fdt32_to_cpu(ptr[0]) << 32);
|
||||
const uint64_t limit = fdt32_to_cpu(ptr[3]) | ((uint64_t)fdt32_to_cpu(ptr[2]) << 32);
|
||||
|
||||
pci_conf_space = (void *)DEVPA2VA(conf_base);
|
||||
pci_conf_size = limit;
|
||||
kprintf("PCI conf space = 0x%p, size = 0x%lx.\n", pci_conf_space, pci_conf_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -136,9 +136,12 @@ PMap_DestroyAS(AS *space)
|
||||
{
|
||||
// free usertables
|
||||
UNUSED struct vmpt * pt = space->user_tbl;
|
||||
|
||||
|
||||
// release space itself
|
||||
PAlloc_Release(space);
|
||||
|
||||
// XXX: release all pdcaches
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,6 +396,7 @@ PMap_SystemUnmap(UNUSED uint64_t virt, UNUSED uint64_t pages)
|
||||
void
|
||||
PMap_Dump(UNUSED AS *space)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ AHCI_Init(uint32_t bus, uint32_t slot, uint32_t func)
|
||||
|
||||
uint32_t device = dev.vendor << 16 | dev.device;
|
||||
|
||||
uint8_t progif = PCI_CfgRead8(&dev, PCI_OFFSET_PROGIF);
|
||||
uint8_t progif = PCI_CfgRead8(&dev, PCI_OFFSET_PROG_INTERFACE);
|
||||
if (progif != 0x01)
|
||||
{
|
||||
kprintf("Unsupported SATA Controller PROGIF=%02x\n", progif);
|
||||
|
@ -34,31 +34,31 @@ PCI_Init()
|
||||
uint16_t
|
||||
PCIGetDeviceID(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_DEVICEID);
|
||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_DEVICE_ID);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PCIGetVendorID(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_VENDORID);
|
||||
return PCICfgRead16(bus, device, func, PCI_OFFSET_VENDOR_ID);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCIGetBaseClass(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_CLASS);
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_BASE_CLASS_CODE);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCIGetSubClass(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_SUBCLASS);
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_SUB_CLASS_CODE);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCIGetHeaderType(uint32_t bus, uint32_t device, uint32_t func)
|
||||
{
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_HEADERTYPE);
|
||||
return PCICfgRead8(bus, device, func, PCI_OFFSET_HEADER_TYPE);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@ -100,31 +100,31 @@ PCI_CfgWrite32(PCIDevice *dev, uint32_t reg, uint32_t data)
|
||||
uint16_t
|
||||
PCI_GetDeviceID(PCIDevice *dev)
|
||||
{
|
||||
return PCI_CfgRead16(dev, PCI_OFFSET_DEVICEID);
|
||||
return PCI_CfgRead16(dev, PCI_OFFSET_DEVICE_ID);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PCI_GetVendorID(PCIDevice *dev)
|
||||
{
|
||||
return PCI_CfgRead16(dev, PCI_OFFSET_VENDORID);
|
||||
return PCI_CfgRead16(dev, PCI_OFFSET_VENDOR_ID);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCI_GetBaseClass(PCIDevice *dev)
|
||||
{
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_CLASS);
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_BASE_CLASS_CODE);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCI_GetSubClass(PCIDevice *dev)
|
||||
{
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_SUBCLASS);
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_SUB_CLASS_CODE);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
PCI_GetHeaderType(PCIDevice *dev)
|
||||
{
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_HEADERTYPE);
|
||||
return PCI_CfgRead8(dev, PCI_OFFSET_HEADER_TYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -250,10 +250,10 @@ PCI_Configure(PCIDevice *dev)
|
||||
{
|
||||
int bar;
|
||||
|
||||
dev->irq = PCI_CfgRead8(dev, PCI_OFFSET_IRQLINE);
|
||||
dev->irq = PCI_CfgRead8(dev, PCI0_INTERRUPT_LINE);
|
||||
|
||||
PCI_CfgWrite16(dev, PCI_OFFSET_COMMAND,
|
||||
PCI_COMMAND_IOENABLE | PCI_COMMAND_MEMENABLE | PCI_COMMAND_BUSMASTER);
|
||||
PCI_CMD_IOSE | PCI_CMD_BME | PCI_CMD_MSE);
|
||||
|
||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||
{
|
||||
@ -264,7 +264,7 @@ PCI_Configure(PCIDevice *dev)
|
||||
|
||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||
{
|
||||
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
||||
uint32_t barReg = PCI0_BASE_ADDR0 + 4 * bar;
|
||||
uint32_t base, size;
|
||||
uint32_t origValue = PCI_CfgRead32(dev, barReg);
|
||||
|
||||
@ -410,12 +410,11 @@ Debug_PCIDump(int argc, const char *argv[])
|
||||
kprintf("Device ID: %04x\n", PCIGetDeviceID(bus, device, func));
|
||||
kprintf("Class: %d\n", PCIGetBaseClass(bus, device, func));
|
||||
kprintf("Subclass: %d\n", PCIGetSubClass(bus, device, func));
|
||||
kprintf("ProgIf: %02x\n", PCICfgRead8(bus, device, func, PCI_OFFSET_PROGIF));
|
||||
kprintf("Header Type: %d\n", PCIGetHeaderType(bus, device, func));
|
||||
|
||||
for (bar = 0; bar < PCI_MAX_BARS; bar++)
|
||||
{
|
||||
uint32_t barReg = PCI_OFFSET_BARFIRST + 4 * bar;
|
||||
uint32_t barReg = PCI0_BASE_ADDR0 + 4 * bar;
|
||||
|
||||
kprintf("BAR%d: %016x\n", bar, PCICfgRead32(bus, device, func, barReg));
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
}
|
||||
|
||||
NO_RETURN void Panic(const char *str, ...);
|
||||
NO_RETURN PRINTF_LIKE void Panic(const char *str, ...);
|
||||
|
||||
#if defined(__aarch64__)
|
||||
NO_RETURN extern void
|
||||
@ -30,7 +30,7 @@ Halt(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int kprintf(const char *fmt, ...);
|
||||
PRINTF_LIKE int kprintf(const char *fmt, ...);
|
||||
int kvprintf(const char *fmt, va_list ap);
|
||||
NO_RETURN void Debug_Assert(const char *fmt, ...);
|
||||
|
||||
|
@ -20,6 +20,7 @@ typedef struct KTime {
|
||||
typedef uint64_t UnixEpoch;
|
||||
typedef uint64_t UnixEpochNS;
|
||||
|
||||
void KTime_Init(void);
|
||||
void KTime_Fixup(KTime *tm);
|
||||
UnixEpoch KTime_ToEpoch(const KTime *tm);
|
||||
void KTime_FromEpoch(UnixEpoch time, KTime *tm);
|
||||
|
@ -14,6 +14,7 @@ typedef struct KTimerEvent {
|
||||
LIST_ENTRY(KTimerEvent) timerQueue;
|
||||
} KTimerEvent;
|
||||
|
||||
void KTimer_Init(void);
|
||||
KTimerEvent *KTimer_Create(uint64_t timeout, KTimerCB cb, void *arg);
|
||||
void KTimer_Retain(KTimerEvent *evt);
|
||||
void KTimer_Release(KTimerEvent *evt);
|
||||
|
@ -1,25 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#define PCI_OFFSET_VENDORID 0x00
|
||||
#define PCI_OFFSET_DEVICEID 0x02
|
||||
#define PCI_OFFSET_COMMAND 0x04
|
||||
#define PCI_OFFSET_STATUS 0x06
|
||||
#define PCI_OFFSET_REVISIONID 0x08
|
||||
#define PCI_OFFSET_PROGIF 0x09
|
||||
#define PCI_OFFSET_SUBCLASS 0x0A
|
||||
#define PCI_OFFSET_CLASS 0x0B
|
||||
#define PCI_OFFSET_CACHELINE 0x0C
|
||||
#define PCI_OFFSET_LATENCYTMR 0x0D
|
||||
#define PCI_OFFSET_HEADERTYPE 0x0E
|
||||
#define PCI_OFFSET_BIST 0x0F
|
||||
#include <stdint.h>
|
||||
|
||||
#define PCI_OFFSET_BARFIRST 0x10
|
||||
#define PCI_OFFSET_BARLAST 0x24
|
||||
#define PCI_OFFSET_VENDOR_ID 0x00 // Vendor ID ro
|
||||
#define PCI_OFFSET_DEVICE_ID 0x02 // Device ID ro
|
||||
#define PCI_OFFSET_COMMAND 0x04 // Command rw
|
||||
#define PCI_OFFSET_STATUS 0x06 // Status rw
|
||||
#define PCI_OFFSET_REVISION_ID 0x08 // Revision ID ro
|
||||
#define PCI_OFFSET_CLASS_CODE 0x09 // Class Code ro
|
||||
#define PCI_OFFSET_PROG_INTERFACE (PCI_OFFSET_CLASS_CODE) // Programming Interface ro
|
||||
#define PCI_OFFSET_SUB_CLASS_CODE 0x0A // Sub Class Code ro
|
||||
#define PCI_OFFSET_BASE_CLASS_CODE 0x0B // Base Class Code ro
|
||||
#define PCI_OFFSET_CACHE_LINE_SIZE 0x0C // Cache Line Size ro+
|
||||
#define PCI_OFFSET_LATENCY_TIMER 0x0D // Latency Timer ro+
|
||||
#define PCI_OFFSET_HEADER_TYPE 0x0E // Header Type ro
|
||||
#define PCI_OFFSET_BIST 0x0F // Built in self test rw
|
||||
|
||||
#define PCI_OFFSET_IRQLINE 0x3C
|
||||
// Type 0 PCI offsets
|
||||
#define PCI0_BASE_ADDR0 0x10 // Base Address 0 rw
|
||||
#define PCI0_BASE_ADDR1 0x14 // Base Address 1 rw
|
||||
#define PCI0_BASE_ADDR2 0x18 // Base Address 2 rw
|
||||
#define PCI0_BASE_ADDR3 0x1C // Base Address 3 rw
|
||||
#define PCI0_BASE_ADDR4 0x20 // Base Address 4 rw
|
||||
#define PCI0_BASE_ADDR5 0x24 // Base Address 5 rw
|
||||
#define PCI0_CIS 0x28 // CardBus CIS Pointer ro
|
||||
#define PCI0_SUB_VENDOR_ID 0x2C // Sub-Vendor ID ro
|
||||
#define PCI0_SUB_SYSTEM_ID 0x2E // Sub-System ID ro
|
||||
#define PCI0_ROM_BASE_ADDR 0x30 // Expansion ROM Base Address rw
|
||||
#define PCI0_CAP_PTR 0x34 // Capability list pointer ro
|
||||
#define PCI0_RESERVED 0x35
|
||||
#define PCI0_INTERRUPT_LINE 0x3C // Interrupt Line rw
|
||||
#define PCI0_INTERRUPT_PIN 0x3D // Interrupt Pin ro
|
||||
#define PCI0_MINIMUM_GRANT 0x3E // Maximum Grant ro
|
||||
#define PCI0_MAXIMUM_LATENCY 0x3F // Maximum Latency ro
|
||||
|
||||
#define PCI_COMMAND_IOENABLE 0x0001
|
||||
#define PCI_COMMAND_MEMENABLE 0x0002
|
||||
#define PCI_COMMAND_BUSMASTER 0x0004
|
||||
// Type 1 PCI offsets
|
||||
#define PCI1_BASE_ADDR0 0x10 // Base Address 0 rw
|
||||
#define PCI1_BASE_ADDR1 0x14 // Base Address 1 rw
|
||||
#define PCI1_PRI_BUS_NUM 0x18 // Primary Bus Number rw
|
||||
#define PCI1_SEC_BUS_NUM 0x19 // Secondary Bus Number rw
|
||||
#define PCI1_SUB_BUS_NUM 0x1A // Subordinate Bus Number rw
|
||||
#define PCI1_SEC_LAT_TIMER 0x1B // Secondary Latency Timer ro+
|
||||
#define PCI1_IO_BASE 0x1C // I/O Base rw
|
||||
#define PCI1_IO_LIMIT 0x1D // I/O Limit rw
|
||||
#define PCI1_SECONDARY_STATUS 0x1E // Secondary Status rw
|
||||
#define PCI1_MEM_BASE 0x20 // Memory Base rw
|
||||
#define PCI1_MEM_LIMIT 0x22 // Memory Limit rw
|
||||
#define PCI1_PRF_MEM_BASE 0x24 // Prefetchable Memory Base rw
|
||||
#define PCI1_PRF_MEM_LIMIT 0x26 // Prefetchable Memory Limit rw
|
||||
#define PCI1_PRF_BASE_UPPER 0x28 // Prefetchable Base Upper 32 rw
|
||||
#define PCI1_PRF_LIMIT_UPPER 0x2C // Prefetchable Limit Upper 32 rw
|
||||
#define PCI1_IO_BASE_UPPER 0x30 // I/O Base Upper 16 bits rw
|
||||
#define PCI1_IO_LIMIT_UPPER 0x32 // I/O Limit Upper 16 bits rw
|
||||
#define PCI1_RESERVED 0x34 // Reserved ro
|
||||
#define PCI1_ROM_BASE_ADDR 0x38 // Expansion ROM Base Address rw
|
||||
#define PCI1_INTR_LINE 0x3C // Interrupt Line rw
|
||||
#define PCI1_INTR_PIN 0x3D // Interrupt Pin ro
|
||||
#define PCI1_BRIDGE_CTRL 0x3E // Bridge Control rw
|
||||
|
||||
// some pci command reg bitfields
|
||||
#define PCI_CMD_BME 0x04 // Bus master function enable
|
||||
#define PCI_CMD_MSE 0x02 // Memory Space Access enable
|
||||
#define PCI_CMD_IOSE 0x01 // I/O space enable
|
||||
|
||||
#define PCI_MAX_BARS 6
|
||||
|
||||
@ -66,7 +108,7 @@ typedef struct PCIDevice
|
||||
PCIBAR bars[PCI_MAX_BARS];
|
||||
} PCIDevice;
|
||||
|
||||
void PCI_Init();
|
||||
void PCI_Init(void);
|
||||
|
||||
uint8_t PCI_CfgRead8(PCIDevice *dev, uint32_t reg);
|
||||
uint16_t PCI_CfgRead16(PCIDevice *dev, uint32_t reg);
|
||||
|
@ -70,11 +70,17 @@ Thread_Init()
|
||||
|
||||
// Kernel Process
|
||||
kernelProcess = Process_Create(NULL, "kernel");
|
||||
if (!kernelProcess) {
|
||||
Panic("Failed to create kernel process.\n");
|
||||
}
|
||||
|
||||
// Create an thread object for current context
|
||||
Process *proc = Process_Create(NULL, "init");
|
||||
curProc[0] = Thread_Create(proc);
|
||||
curProc[0]->schedState = SCHED_STATE_RUNNING;
|
||||
if (!proc) {
|
||||
Panic("Failed to create init process.\n");
|
||||
}
|
||||
curProc[CPU()] = Thread_Create(proc);
|
||||
curProc[CPU()]->schedState = SCHED_STATE_RUNNING;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user