@@ -35,13 +35,15 @@ void detect_ahci_devices(ahci_controller* ahci_ctrl) {
35
35
printf ("SATA Disk detected at port %d" , i );
36
36
uint8_t sector_buffer [SECTOR_SIZE * 1 ]; // Buffer to store 5 sectors
37
37
38
- if (read_sectors (0 , 1 , sector_buffer ) != 0 ) {
38
+ if (read_sectors (1 , 1 , sector_buffer ) != 0 ) {
39
39
error ("sector reading failed!" , __FILE__ );
40
40
}
41
41
42
42
// for(int x = 0; x < SECTOR_SIZE * 1; x++){
43
- // debug_printf("%u ", sector_buffer[x]);
43
+ // debug_printf("%u ", (int) sector_buffer[x]);
44
44
// }
45
+ // debug_print("\n");
46
+
45
47
} else if (sig == satapi_disk ) {
46
48
printf ("SATAPI Disk detected at port %d" , i );
47
49
} else if (sig == semb_disk ) {
@@ -75,35 +77,81 @@ prdt_entry_t* allocate_prdt(size_t num_entries) {
75
77
return (prdt_entry_t * )malloc (num_entries * sizeof (prdt_entry_t ));
76
78
}
77
79
80
+ prdt_entry_t * free_prdt (prdt_entry_t * a ) {
81
+ return (prdt_entry_t * )free (a );
82
+ }
83
+
78
84
int read_sectors (uint32_t lba , uint32_t sector_count , void * buffer ) {
79
- // 1. Get AHCI command header and PRDT
85
+ if (sector_count == 0 ) return -1 ; // Handle invalid input
86
+
80
87
ahci_command_header_t * cmd_header = get_free_command_header ();
88
+ if (!cmd_header ) return -1 ; // Handle allocation failure
89
+
81
90
prdt_entry_t * prdt = allocate_prdt (1 );
91
+ if (!prdt ) {
92
+ // free_command_header(cmd_header);
93
+ return -1 ;
94
+ }
82
95
83
- // 2. Fill command FIS
84
- cmd_header -> cfis [0 ] = 0x27 ; // ATA command: Read
85
- cmd_header -> cfis [2 ] = lba & 0xFF ;
86
- cmd_header -> cfis [3 ] = (lba >> 8 ) & 0xFF ;
87
- cmd_header -> cfis [4 ] = (lba >> 16 ) & 0xFF ;
88
- cmd_header -> cfis [5 ] = (lba >> 24 ) & 0xFF ;
89
- cmd_header -> cfis [7 ] = sector_count & 0xFF ;
90
- cmd_header -> cfis [8 ] = (sector_count >> 8 ) & 0xFF ;
91
-
92
- // 3. Fill PRDT
93
- prdt [0 ].dba = (uint32_t )buffer ; // Address of the buffer to store data
94
- prdt [0 ].dbc = sector_count * SECTOR_SIZE - 1 ; // Number of bytes to transfer
95
-
96
- // 4. Set up command header
97
- cmd_header -> prdtl = sizeof (prdt_entry_t ); // Size of PRDT
96
+ // 1. Fill command FIS (Corrected for 48-bit LBA if needed)
97
+ cmd_header -> cfis [0 ] = 0x20 ; // ATA command: Read (0x20 for 28-bit, 0x24 for 48-bit)
98
+
99
+ if (lba > 0xFFFFFFF || (lba + sector_count ) > 0xFFFFFFF ) { // Check for 28-bit overflow
100
+ cmd_header -> cfis [0 ] = 0x24 ; // Use 48-bit command if needed
101
+ cmd_header -> cfis [1 ] = 0 ;
102
+ cmd_header -> cfis [2 ] = lba & 0xFF ;
103
+ cmd_header -> cfis [3 ] = (lba >> 8 ) & 0xFF ;
104
+ cmd_header -> cfis [4 ] = (lba >> 16 ) & 0xFF ;
105
+ cmd_header -> cfis [5 ] = (lba >> 24 ) & 0xFF ;
106
+ cmd_header -> cfis [6 ] = (lba >> 32 ) & 0xFF ; // LBA 48 bit
107
+ cmd_header -> cfis [7 ] = (lba >> 40 ) & 0xFF ; // LBA 48 bit
108
+ cmd_header -> cfis [8 ] = sector_count & 0xFF ;
109
+ cmd_header -> cfis [9 ] = (sector_count >> 8 ) & 0xFF ; // Sector count 16 bit
110
+ } else {
111
+ cmd_header -> cfis [2 ] = lba & 0xFF ;
112
+ cmd_header -> cfis [3 ] = (lba >> 8 ) & 0xFF ;
113
+ cmd_header -> cfis [4 ] = (lba >> 16 ) & 0xFF ;
114
+ cmd_header -> cfis [5 ] = (lba >> 24 ) & 0xFF ;
115
+ cmd_header -> cfis [7 ] = sector_count & 0xFF ;
116
+ cmd_header -> cfis [8 ] = (sector_count >> 8 ) & 0xFF ;
117
+ }
118
+
119
+
120
+ // 2. Fill PRDT (Corrected DBC)
121
+ prdt [0 ].dba = (uint32_t )buffer ;
122
+ prdt [0 ].dbc = sector_count * SECTOR_SIZE - 1 ; // Byte count, not sector count
123
+
124
+ // 3. Set up command header
125
+ cmd_header -> prdtl = 1 ; // Number of PRDT entries, not size in bytes.
98
126
cmd_header -> prdt = (uint32_t )prdt ;
99
127
100
- // 5 . Issue the command
101
- cmd_header -> ci = 1 ; // Issue command
128
+ // 4 . Issue the command
129
+ cmd_header -> ci = 1 ;
102
130
131
+ // 5. **CRITICAL:** Wait for command completion. This is the most likely source of your original problem.
132
+ wait_for_command_completion (cmd_header );
103
133
104
- sleep (2 );
134
+ // 6. Check for errors (add this!)
135
+ if (cmd_header -> ciss & 0x1 ) { // Error bit set
136
+ // free_command_header(cmd_header);
137
+ free_prdt (prdt );
138
+ return -1 ; // Or a more specific error code.
139
+ }
140
+
141
+ // free_command_header(cmd_header);
142
+ free_prdt (prdt );
105
143
106
- // 7. Read data from the buffer
144
+ return 0 ;
145
+ }
107
146
108
- return 0 ; // Command successful
109
- }
147
+ void wait_for_command_completion (ahci_command_header_t * cmd_header ) {
148
+ volatile uint32_t * status_reg = (volatile uint32_t * )(cmd_header + 0x08 ); // Example, adjust as needed.
149
+ while (1 ) {
150
+ if (! (status_reg [0 ] & (1 << 7 ))) { // Check BSY (Busy) bit in PxSATASTATUS register
151
+ break ;
152
+ }
153
+ }
154
+
155
+ // Check the command complete (CC) bit in the command header.
156
+ // while (cmd_header->ci) ; // Wait for CI to clear (command complete)
157
+ }
0 commit comments