Skip to content

Commit daf8573

Browse files
Hendiadyoin1AtkinsSJ
authored andcommitted
Kernel: Make SDHC InterruptStatus a bitfield
A raw accessor was left as a means to use already existing codepaths.
1 parent 35ec96f commit daf8573

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

Kernel/Storage/SD/Registers.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,40 @@ struct HostControlRegisterMap {
3838
u32 present_state;
3939
u32 host_configuration_0;
4040
u32 host_configuration_1;
41-
u32 interrupt_status;
41+
union InterruptStatus {
42+
struct { // SDHC 2.2.18 Normal Interrupt Status Register (Cat.C Offset 030h)
43+
u32 command_complete : 1;
44+
u32 transfer_complete : 1;
45+
u32 block_gap_event : 1;
46+
u32 dma_interrupt : 1;
47+
u32 buffer_write_ready : 1;
48+
u32 buffer_read_ready : 1;
49+
u32 card_insertion : 1;
50+
u32 card_removal : 1;
51+
u32 card_interrupt : 1;
52+
u32 int_a : 1;
53+
u32 int_b : 1;
54+
u32 int_c : 1;
55+
u32 retuning_event : 1;
56+
u32 fx_event : 1;
57+
u32 : 1;
58+
u32 error_interrupt : 1;
59+
// SDHC 2.2.19 Error Interrupt Status Register (Cat.C Offset 032
60+
u32 command_timeout_error : 1;
61+
u32 command_crc_error : 1;
62+
u32 cammand_index_error : 1;
63+
u32 data_timeout_error : 1;
64+
u32 data_crc_error : 1;
65+
u32 data_end_bit_error : 1;
66+
u32 current_limit_error : 1;
67+
u32 auto_cmd_error : 1;
68+
u32 adma_error : 1;
69+
u32 tuning_error : 1;
70+
u32 response_error : 1;
71+
u32 vendor_specific_error : 1;
72+
};
73+
u32 raw;
74+
} interrupt_status;
4275
u32 interrupt_status_enable;
4376
u32 interrupt_signal_enable;
4477
u32 host_configuration_2;

Kernel/Storage/SD/SDHostController.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,12 @@ ErrorOr<SDHostController::Response> SDHostController::wait_for_response()
276276
// 1. Wait for the Command Complete Interrupt. If the Command Complete
277277
// Interrupt has occurred, go to step (2).
278278
if (!retry_with_timeout(
279-
[&]() { return m_registers->interrupt_status & command_complete; })) {
279+
[&]() { return m_registers->interrupt_status.command_complete; })) {
280280
return EIO;
281281
}
282282

283283
// 2. Write 1 to Command Complete in the Normal Interrupt Status register to clear this bit
284-
m_registers->interrupt_status = command_complete;
284+
m_registers->interrupt_status.raw = command_complete;
285285

286286
// 3. Read the Response register(s) to get the response.
287287
// NOTE: We read fewer bits than ResponseType because the missing bits are only
@@ -483,14 +483,13 @@ ErrorOr<void> SDHostController::transaction_control_with_data_transfer_using_the
483483
m_registers->transfer_mode_and_command = command.raw;
484484

485485
// 6. Then, wait for the Command Complete Interrupt.
486-
if (!retry_with_timeout(
487-
[&]() { return m_registers->interrupt_status & command_complete; })) {
486+
if (!retry_with_timeout([&]() { return m_registers->interrupt_status.command_complete; })) {
488487
return EIO;
489488
}
490489

491490
// 7. Write 1 to the Command Complete in the Normal Interrupt Status
492491
// register for clearing this bit.
493-
m_registers->interrupt_status = command_complete;
492+
m_registers->interrupt_status.raw = command_complete;
494493

495494
// 8. Read Response register and get necessary information of the issued
496495
// command
@@ -505,13 +504,13 @@ ErrorOr<void> SDHostController::transaction_control_with_data_transfer_using_the
505504
// 10. Then wait for Buffer Write Ready Interrupt.
506505
if (!retry_with_timeout(
507506
[&]() {
508-
return m_registers->interrupt_status & buffer_write_ready;
507+
return m_registers->interrupt_status.buffer_write_ready;
509508
})) {
510509
return EIO;
511510
}
512511

513512
// 11. Write 1 to the Buffer Write Ready in the Normal Interrupt Status register for clearing this bit.
514-
m_registers->interrupt_status = buffer_write_ready;
513+
m_registers->interrupt_status.raw = buffer_write_ready;
515514

516515
// 12. Write block data (in according to the number of bytes specified at the step (1)) to Buffer Data Port register.
517516
u32 temp;
@@ -525,13 +524,13 @@ ErrorOr<void> SDHostController::transaction_control_with_data_transfer_using_the
525524
} else {
526525
for (u32 i = 0; i < block_count; i++) {
527526
// 14. Then wait for the Buffer Read Ready Interrupt.
528-
if (!retry_with_timeout([&]() { return m_registers->interrupt_status & buffer_read_ready; })) {
527+
if (!retry_with_timeout([&]() { return m_registers->interrupt_status.buffer_read_ready; })) {
529528
return EIO;
530529
}
531530

532531
// 15. Write 1 to the Buffer Read Ready in the Normal Interrupt Status
533532
// register for clearing this bit.
534-
m_registers->interrupt_status = buffer_read_ready;
533+
m_registers->interrupt_status.raw = buffer_read_ready;
535534

536535
// 16. Read block data (in according to the number of bytes specified at
537536
// the step (1)) from the Buffer Data Port register
@@ -550,14 +549,13 @@ ErrorOr<void> SDHostController::transaction_control_with_data_transfer_using_the
550549

551550
// 19. Wait for Transfer Complete Interrupt.
552551
if (!retry_with_timeout(
553-
[&]() { return m_registers->interrupt_status & transfer_complete; })) {
552+
[&]() { return m_registers->interrupt_status.transfer_complete; })) {
554553
return EIO;
555554
}
556555

557556
// 20. Write 1 to the Transfer Complete in the Normal Interrupt Status
558557
// register for clearing this bit
559-
m_registers->interrupt_status = transfer_complete;
560-
558+
m_registers->interrupt_status.raw = transfer_complete;
561559
return {};
562560
}
563561

0 commit comments

Comments
 (0)