aboutsummaryrefslogtreecommitdiff
path: root/src/disk.h
blob: 7feb9afec0c4998f60ce2a0fb8aa485159fc861e (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// Definitions for X86 bios disks.
//
// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
#ifndef __DISK_H
#define __DISK_H

#include "types.h" // u8
#include "config.h" // CONFIG_*
#include "farptr.h" // struct segoff_s

#define DISK_RET_SUCCESS       0x00
#define DISK_RET_EPARAM        0x01
#define DISK_RET_EADDRNOTFOUND 0x02
#define DISK_RET_EWRITEPROTECT 0x03
#define DISK_RET_ECHANGED      0x06
#define DISK_RET_EBOUNDARY     0x09
#define DISK_RET_EBADTRACK     0x0c
#define DISK_RET_ECONTROLLER   0x20
#define DISK_RET_ETIMEOUT      0x80
#define DISK_RET_ENOTLOCKED    0xb0
#define DISK_RET_ELOCKED       0xb1
#define DISK_RET_ENOTREMOVABLE 0xb2
#define DISK_RET_ETOOMANYLOCKS 0xb4
#define DISK_RET_EMEDIA        0xC0
#define DISK_RET_ENOTREADY     0xAA


/****************************************************************
 * Interface structs
 ****************************************************************/

// Bios disk structures.
struct int13ext_s {
    u8  size;
    u8  reserved;
    u16 count;
    struct segoff_s data;
    u64 lba;
} PACKED;

#define GET_INT13EXT(regs,var)                                          \
    GET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var)
#define SET_INT13EXT(regs,var,val)                                      \
    SET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var, (val))

// Disk Physical Table definition
struct int13dpt_s {
    u16 size;
    u16 infos;
    u32 cylinders;
    u32 heads;
    u32 spt;
    u64 sector_count;
    u16 blksize;
    u16 dpte_offset;
    u16 dpte_segment;
    u16 key;
    u8  dpi_length;
    u8  reserved1;
    u16 reserved2;
    u8  host_bus[4];
    u8  iface_type[8];
    u64 iface_path;
    u64 device_path;
    u8  reserved3;
    u8  checksum;
} PACKED;

#define GET_INT13DPT(regs,var)                                          \
    GET_FARVAR((regs)->ds, ((struct int13dpt_s*)((regs)->si+0))->var)
#define SET_INT13DPT(regs,var,val)                                      \
    SET_FARVAR((regs)->ds, ((struct int13dpt_s*)((regs)->si+0))->var, (val))

// Floppy "Disk Base Table"
struct floppy_dbt_s {
    u8 specify1;
    u8 specify2;
    u8 shutoff_ticks;
    u8 bps_code;
    u8 sectors;
    u8 interblock_len;
    u8 data_len;
    u8 gap_len;
    u8 fill_byte;
    u8 settle_time;
    u8 startup_time;
} PACKED;

struct floppy_ext_dbt_s {
    struct floppy_dbt_s dbt;
    // Extra fields
    u8 max_track;
    u8 data_rate;
    u8 drive_type;
} PACKED;

// Helper function for setting up a return code.
struct bregs;
void __disk_ret(struct bregs *regs, u32 linecode, const char *fname);
#define disk_ret(regs, code) \
    __disk_ret((regs), (code) | (__LINE__ << 8), __func__)
void __disk_ret_unimplemented(struct bregs *regs, u32 linecode
                              , const char *fname);
#define disk_ret_unimplemented(regs, code) \
    __disk_ret_unimplemented((regs), (code) | (__LINE__ << 8), __func__)


/****************************************************************
 * Master boot record
 ****************************************************************/

struct packed_chs_s {
    u8 heads;
    u8 sptcyl;
    u8 cyllow;
};

struct partition_s {
    u8 status;
    struct packed_chs_s first;
    u8 type;
    struct packed_chs_s last;
    u32 lba;
    u32 count;
} PACKED;

struct mbr_s {
    u8 code[440];
    // 0x01b8
    u32 diskseg;
    // 0x01bc
    u16 null;
    // 0x01be
    struct partition_s partitions[4];
    // 0x01fe
    u16 signature;
} PACKED;

#define MBR_SIGNATURE 0xaa55


/****************************************************************
 * Disk command request
 ****************************************************************/

struct disk_op_s {
    u64 lba;
    void *buf_fl;
    struct drive_s *drive_g;
    u16 count;
    u8 command;
};

#define CMD_RESET   0x00
#define CMD_READ    0x02
#define CMD_WRITE   0x03
#define CMD_VERIFY  0x04
#define CMD_FORMAT  0x05
#define CMD_SEEK    0x07
#define CMD_ISREADY 0x10


/****************************************************************
 * Global storage
 ****************************************************************/

struct chs_s {
    u16 heads;      // # heads
    u16 cylinders;  // # cylinders
    u16 spt;        // # sectors / track
};

struct drive_s {
    u8  type;         // Detected type of drive (ata/atapi/none)
    u8  removable;    // Removable device flag
    u16 blksize;      // block size
    u32 cntl_id;
    u32 cntl_info;
    u8  floppy_type;  // Type of floppy (only for floppy drives).

    char model[41];

    u8  translation;  // type of translation
    struct chs_s  lchs;         // Logical CHS
    struct chs_s  pchs;         // Physical CHS

    u64 sectors;      // Total sectors count
};

#define DISK_SECTOR_SIZE  512
#define CDROM_SECTOR_SIZE 2048

#define DTYPE_NONE     0x00
#define DTYPE_FLOPPY   0x01
#define DTYPE_ATA      0x02
#define DTYPE_ATAPI    0x03
#define DTYPE_RAMDISK  0x04
#define DTYPE_CDEMU    0x05

#define TRANSLATION_NONE  0
#define TRANSLATION_LBA   1
#define TRANSLATION_LARGE 2
#define TRANSLATION_RECHS 3

struct drives_s {
    // info on each internally handled drive
    struct drive_s drives[CONFIG_MAX_DRIVES];
    u8 drivecount;
    //
    // map between bios floppy/hd/cd id and driveid index into drives[]
    u8 floppycount;
    u8 cdcount;
    u8 idmap[3][CONFIG_MAX_EXTDRIVE];
};

#define EXTTYPE_FLOPPY 0
#define EXTTYPE_HD 1
#define EXTTYPE_CD 2

#define EXTSTART_HD 0x80
#define EXTSTART_CD 0xE0


/****************************************************************
 * Function defs
 ****************************************************************/

// block.c
extern struct drives_s Drives;
struct drive_s *getDrive(u8 exttype, u8 extdriveoffset);
struct drive_s *allocDrive();
void setup_translation(struct drive_s *drive_g);
void map_floppy_drive(struct drive_s *drive_g);
void map_hd_drive(struct drive_s *drive_g);
void map_cd_drive(struct drive_s *drive_g);
void describe_drive(struct drive_s *drive_g);
int process_op(struct disk_op_s *op);
int send_disk_op(struct disk_op_s *op);
void drive_setup();

// floppy.c
extern struct floppy_ext_dbt_s diskette_param_table2;
void floppy_setup();
struct drive_s *addFloppy(int floppyid, int ftype, int driver);
void describe_floppy(struct drive_s *drive_g);
int find_floppy_type(u32 size);
int process_floppy_op(struct disk_op_s *op);
void floppy_tick();

// cdrom.c
extern struct drive_s *cdemu_drive;
int process_cdemu_op(struct disk_op_s *op);
void cdemu_setup();
void cdemu_134b(struct bregs *regs);
int cdrom_boot(int cdid);

// ramdisk.c
void describe_ramdisk(struct drive_s *drive_g);
void ramdisk_setup();
int process_ramdisk_op(struct disk_op_s *op);

#endif // disk.h