blob: a0cd12a0468bc02f22298b1de25e74096822ccb8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
/*
RCC-Project
Copyright (C) 2026 Richard Qin
This file is part of RCC-Project.
RCC-Project is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
RCC-Project; see the file COPYING. If not see
<http://www.gnu.org/licenses/>.
*/
#include "bios.h"
#include "io.h"
#define ATA_DATA 0x1F0u
#define ATA_SECTOR_COUNT 0x1F2u
#define ATA_LBA_LOW 0x1F3u
#define ATA_LBA_MID 0x1F4u
#define ATA_LBA_HIGH 0x1F5u
#define ATA_DRIVE 0x1F6u
#define ATA_STATUS 0x1F7u
#define ATA_COMMAND 0x1F7u
#define ATA_STATUS_ERR 0x01u
#define ATA_STATUS_DRQ 0x08u
#define ATA_STATUS_BSY 0x80u
#define ATA_CMD_READ_SECTORS 0x20u
static u8
ata_wait_not_busy (void)
{
u8 status;
do
{
status = io_in8 (ATA_STATUS);
}
while ((status & ATA_STATUS_BSY) != 0);
return status;
}
static void
ata_delay_400ns (void)
{
io_in8 (ATA_STATUS);
io_in8 (ATA_STATUS);
io_in8 (ATA_STATUS);
io_in8 (ATA_STATUS);
}
u8
ata_read_sector28 (u32 lba, u16 *buffer)
{
u8 status;
u16 index;
status = ata_wait_not_busy ();
if ((status & ATA_STATUS_ERR) != 0)
return 1;
io_out8 (ATA_DRIVE, (u8)(0xE0u | ((lba >> 24) & 0x0Fu)));
ata_delay_400ns ();
io_out8 (ATA_SECTOR_COUNT, 1);
io_out8 (ATA_LBA_LOW, (u8)(lba & 0xFFu));
io_out8 (ATA_LBA_MID, (u8)((lba >> 8) & 0xFFu));
io_out8 (ATA_LBA_HIGH, (u8)((lba >> 16) & 0xFFu));
io_out8 (ATA_COMMAND, ATA_CMD_READ_SECTORS);
status = ata_wait_not_busy ();
if ((status & ATA_STATUS_ERR) != 0)
return 1;
if ((status & ATA_STATUS_DRQ) == 0)
return 1;
for (index = 0; index < 256; ++index)
buffer[index] = io_in16 (ATA_DATA);
return 0;
}
|