Skip to content

Commit 911c4a3

Browse files
committed
Impl reset via ACPI
1 parent 96a337a commit 911c4a3

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

src/acpi.h

+8
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ packed_struct GAS {
293293
uint8_t reserved;
294294
void* address;
295295
};
296+
static_assert(sizeof(GAS) == 12);
296297

297298
packed_struct HPET {
298299
char signature[4];
@@ -357,6 +358,13 @@ packed_struct FADT {
357358
uint32_t smi_cmd;
358359
uint8_t acpi_enable;
359360
uint8_t acpi_disable;
361+
362+
uint16_t GetResetReg() {
363+
return reinterpret_cast<uint64_t>(reinterpret_cast<GAS *>(reinterpret_cast<uint64_t>(this) + 116)->address);
364+
}
365+
uint8_t GetResetValue() {
366+
return reinterpret_cast<uint8_t *>(this)[128];
367+
}
360368
};
361369
static_assert(sizeof(FADT) == 54);
362370

src/command.cc

+16
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,20 @@ void ShowFADT() {
320320
PutStringAndHex("smi_cmd", fadt.smi_cmd);
321321
PutStringAndHex("acpi_enable", fadt.acpi_enable);
322322
PutStringAndHex("acpi_disable", fadt.acpi_disable);
323+
PutStringAndHex("reset_register", fadt.GetResetReg());
324+
PutStringAndHex("reset_value", fadt.GetResetValue());
325+
}
326+
327+
void Reset() {
328+
using namespace ACPI;
329+
if (!liumos->acpi.fadt) {
330+
PutString("FADT not found.\n");
331+
return;
332+
}
333+
FADT& fadt = *liumos->acpi.fadt;
334+
WriteIOPort8(fadt.GetResetReg(), fadt.GetResetValue());
335+
for (;;) {
336+
}
323337
}
324338

325339
void ShowEFIMemoryMap() {
@@ -577,6 +591,8 @@ void Run(TextBox& tbox) {
577591
const char* line = tbox.GetRecordedString();
578592
if (IsEqualString(line, "hello")) {
579593
PutString("Hello, world!\n");
594+
} else if (IsEqualString(line, "reset")) {
595+
Reset();
580596
} else if (IsEqualString(line, "show xsdt")) {
581597
ShowXSDT();
582598
} else if (IsEqualString(line, "show nfit")) {

src/xhci.cc

+30-1
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,20 @@ void Controller::Init() {
245245
NotifyHostControllerDoorbell();
246246

247247
// 4.3.1 Resetting a Root Hub Port
248+
/*
248249
for (int slot = 1; slot <= num_of_slots_enabled_; slot++) {
249250
ResetPort(slot);
250251
}
252+
*/
253+
for (int port = 1; port <= max_ports_; port++) {
254+
uint32_t portsc = ReadPORTSC(port);
255+
if(!portsc) continue;
256+
PutStringAndHex("port", port);
257+
PutStringAndHex(" PORTSC", portsc);
258+
if(portsc & 1 && port_state_[port] == kDisconnected) {
259+
port_state_[port] = kNeedsPortReset;
260+
}
261+
}
251262
}
252263

253264
void Controller::ResetPort(int port) {
@@ -318,6 +329,10 @@ class Controller::DeviceContext {
318329
endpoint_ctx[kDCISlotContext][0] =
319330
CombineFieldBits<31, 27>(endpoint_ctx[kDCISlotContext][0], num_of_ent);
320331
}
332+
void SetPortSpeed(uint32_t port_speed) {
333+
endpoint_ctx[kDCISlotContext][0] = CombineFieldBits<23, 20>(
334+
endpoint_ctx[kDCISlotContext][0], port_speed);
335+
}
321336
void SetRootHubPortNumber(uint32_t root_port_num) {
322337
endpoint_ctx[kDCISlotContext][1] = CombineFieldBits<23, 16>(
323338
endpoint_ctx[kDCISlotContext][1], root_port_num);
@@ -415,6 +430,7 @@ class Controller::InputContext {
415430
};
416431
static_assert(sizeof(Controller::InputContext) == 0x420);
417432

433+
constexpr uint32_t kPortSpeedFS = 1;
418434
constexpr uint32_t kPortSpeedLS = 2;
419435
constexpr uint32_t kPortSpeedHS = 3;
420436
constexpr uint32_t kPortSpeedSS = 4;
@@ -426,7 +442,7 @@ static uint16_t GetMaxPacketSizeFromPORTSCPortSpeed(uint32_t port_speed) {
426442
// • Max Packet Size = The default maximum packet size for the Default
427443
// Control Endpoint, as function of the PORTSC Port Speed field.
428444
// 7.2.2.1.1 Default USB Speed ID Mapping
429-
if (port_speed == kPortSpeedLS)
445+
if (port_speed == kPortSpeedLS || port_speed || kPortSpeedFS)
430446
return 8;
431447
if (port_speed == kPortSpeedHS)
432448
return 64;
@@ -436,13 +452,16 @@ static uint16_t GetMaxPacketSizeFromPORTSCPortSpeed(uint32_t port_speed) {
436452
}
437453

438454
static const char* GetSpeedNameFromPORTSCPortSpeed(uint32_t port_speed) {
455+
if (port_speed == kPortSpeedFS)
456+
return "Full-speed";
439457
if (port_speed == kPortSpeedLS)
440458
return "Low-speed";
441459
if (port_speed == kPortSpeedHS)
442460
return "High-speed";
443461
if (port_speed == kPortSpeedSS)
444462
return "SuperSpeed Gen1 x1";
445463
PutString("GetSpeedNameFromPORTSCPortSpeed: Not supported speed\n");
464+
PutStringAndHex(" port_speed", port_speed);
446465
return nullptr;
447466
}
448467

@@ -474,6 +493,7 @@ void Controller::HandleEnableSlotCompleted(int slot, int port) {
474493
// 5. Initialize the Input default control Endpoint 0 Context (6.2.3)
475494
uint32_t portsc = ReadPORTSC(port);
476495
uint32_t port_speed = GetBits<13, 10, uint32_t, uint32_t>(portsc);
496+
dctx.SetPortSpeed(port_speed);
477497
PutString(" Port Speed: ");
478498
const char* speed_str = GetSpeedNameFromPORTSCPortSpeed(port_speed);
479499
if (!speed_str) {
@@ -945,6 +965,13 @@ void Controller::CheckPortAndInitiateProcess() {
945965
return;
946966
}
947967
}
968+
for (int i = 0; i < kMaxNumOfPorts; i++) {
969+
if (port_state_[i] == kNeedsPortReset) {
970+
ResetPort(i);
971+
port_state_[i] = kNeedsInitializing;
972+
return;
973+
}
974+
}
948975
}
949976

950977
void Controller::PollEvents() {
@@ -1005,11 +1032,13 @@ void Controller::PollEvents() {
10051032
}
10061033
break;
10071034
case kTRBTypePortStatusChangeEvent:
1035+
/*
10081036
if (e.IsCompletedWithSuccess()) {
10091037
HandlePortStatusChange(
10101038
static_cast<int>(GetBits<31, 24, uint64_t>(e.data)));
10111039
break;
10121040
}
1041+
*/
10131042
PutString("PortStatusChangeEvent\n");
10141043
e.PrintCompletionCode();
10151044
break;

src/xhci.h

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ class Controller {
222222
RingBuffer<uint16_t, 16> keyid_buffer_;
223223
enum PortState {
224224
kDisconnected,
225+
kNeedsPortReset,
225226
kNeedsInitializing,
226227
kInitializing,
227228
kInitialized,

0 commit comments

Comments
 (0)