MCPcopy Create free account
hub / github.com/LemonOSProject/LemonOS / Controller

Method Controller

Kernel/src/storage/nvme.cpp:82–167  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

80 }
81
82 Controller::Controller(PCIDevice* pciDev){
83 pciDevice = pciDev;
84
85 cRegs = reinterpret_cast<Registers*>(Memory::KernelAllocate4KPages(4));
86 Memory::KernelMapVirtualMemory4K(pciDevice->GetBaseAddressRegister(0), (uintptr_t)cRegs, 4);
87
88 pciDevice->EnableBusMastering();
89 pciDevice->EnableMemorySpace();
90 pciDevice->EnableInterrupts();
91
92 Disable();
93
94 {
95 unsigned spin = 500;
96 while(spin-- && (cRegs->status & NVME_CSTS_READY)) Timer::Wait(1);
97
98 if(spin <= 0){
99 Log::Warning("[NVMe] Controller not disabled! (NVME_CSTS_READY == 1)");
100 dStatus = DriverStatus::ControllerError;
101 return;
102 }
103 }
104
105 cRegs->config = NVME_CFG_DEFAULT_IOCQES | NVME_CFG_DEFAULT_IOSQES;
106
107 if(GetMinMemoryPageSize() > PAGE_SIZE_4K || GetMaxMemoryPageSize() < PAGE_SIZE_4K){
108 Log::Error("[NVMe] Error: Controller does not support 4K pages");
109 return;
110 }
111
112 SetMemoryPageSize(PAGE_SIZE_4K);
113 SetCommandSet(NVMeConfigCmdSetNVM);
114
115 uintptr_t admCQBase = Memory::AllocatePhysicalMemoryBlock();
116 uintptr_t admSQBase = Memory::AllocatePhysicalMemoryBlock();
117 void* admCQ = Memory::KernelAllocate4KPages(1);
118 void* admSQ = Memory::KernelAllocate4KPages(1);
119
120 cRegs->adminCompletionQ = admCQBase;
121 cRegs->adminSubmissionQ = admSQBase;
122
123 Memory::KernelMapVirtualMemory4K(admCQBase, (uintptr_t)admCQ, 1);
124 Memory::KernelMapVirtualMemory4K(admSQBase, (uintptr_t)admSQ, 1);
125
126 adminQueue = NVMeQueue(0 /* admin queue ID is 0 */, admCQBase, admSQBase, admCQ, admSQ, GetCompletionDoorbell(0), GetSubmissionDoorbell(0), MIN(PAGE_SIZE_4K, GetMaxQueueEntries() * sizeof(NVMeCompletion)), MIN(PAGE_SIZE_4K, GetMaxQueueEntries() * sizeof(NVMeCommand)));
127
128 SetAdminCompletionQueueSize(adminQueue.CQSize());
129 SetAdminSubmissionQueueSize(adminQueue.SQSize());
130
131 Enable();
132
133 {
134 unsigned spin = 500;
135 while(spin-- && !(cRegs->status & NVME_CSTS_READY)) Timer::Wait(1);
136
137 if(spin <= 0){
138 Log::Warning("[NVMe] Controller not ready! (NVME_CSTS_READY != 1)");
139 dStatus = DriverStatus::ControllerError;

Callers

nothing calls this directly

Calls 15

KernelAllocate4KPagesFunction · 0.85
KernelMapVirtualMemory4KFunction · 0.85
WarningFunction · 0.85
ErrorFunction · 0.85
NVMeQueueClass · 0.85
EnableFunction · 0.85
memcpyFunction · 0.85
InfoFunction · 0.85
EnableBusMasteringMethod · 0.80
EnableMemorySpaceMethod · 0.80

Tested by

no test coverage detected