~ubuntu-branches/ubuntu/trusty/virtualbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Devices/PC/BIOS/ahci.c

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2013-03-07 16:38:36 UTC
  • mfrom: (1.1.13) (3.1.20 experimental)
  • Revision ID: package-import@ubuntu.com-20130307163836-p93jpbgx39tp3gb4
Tags: 4.2.8-dfsg-0ubuntu1
* New upstream release. (Closes: #691148)
  - Fixes compatibility with kernel 3.8. (Closes: #700823; LP: #1101867)
* Switch to my @debian.org email address.
* Move package to contrib as virtualbox 4.2 needs a non-free compiler to
  build the BIOS.
* Build-depend on libdevmapper-dev.
* Refresh patches.
  - Drop 36-fix-ftbfs-xserver-112.patch, cve-2012-3221.patch,
    CVE-2013-0420.patch 37-kcompat-3.6.patch and 38-kcompat-3.7.patch.
* Drop all virtualbox-ose transitional packages.
* Drop the virtualbox-fuse package as vdfuse fails to build with
  virtualbox 4.2.
* Update install files and VBox.sh.
* Bump required kbuild version to 0.1.9998svn2577.
* Fix path to VBoxCreateUSBNode.sh in virtualbox.postinst. (Closes: #700479)
* Add an init script to virtuabox-guest-x11 which loads the vboxvideo
  kernel module. The X Server 1.13 doesn't load it anymore. (Closes: #686994)
* Update man pages. (Closes: #680053)
* Add 36-python-multiarch.patch from Rico Tzschichholz to fix detection of
  python in multiarch paths using pkg-config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 */
5
5
 
6
6
/*
7
 
 * Copyright (C) 2011 Oracle Corporation
 
7
 * Copyright (C) 2011-2012 Oracle Corporation
8
8
 *
9
9
 * This file is part of VirtualBox Open Source Edition (OSE), as
10
10
 * available from http://www.virtualbox.org. This file is free software;
14
14
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15
15
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16
16
 */
17
 
/**
18
 
 * Parts are based on the int13_harddisk code in rombios.c
19
 
 */
20
 
 
21
 
#define AHCI_MAX_STORAGE_DEVICES 4
22
 
 
23
 
/**
24
 
 * AHCI device data.
 
17
 
 
18
#include <stdint.h>
 
19
#include <string.h>
 
20
#include "biosint.h"
 
21
#include "ebda.h"
 
22
#include "inlines.h"
 
23
#include "pciutil.h"
 
24
#include "vds.h"
 
25
 
 
26
#if DEBUG_AHCI
 
27
# define DBG_AHCI(...)        BX_INFO(__VA_ARGS__)
 
28
#else
 
29
# define DBG_AHCI(...)
 
30
#endif
 
31
 
 
32
/* Number of S/G table entries in EDDS. */
 
33
#define NUM_EDDS_SG         16
 
34
 
 
35
 
 
36
/**
 
37
 * AHCI PRDT structure.
25
38
 */
26
39
typedef struct
27
40
{
28
 
    Bit8u  type;         // Detected type of ata (ata/atapi/none/unknown/scsi)
29
 
    Bit8u  device;       // Detected type of attached devices (hd/cd/none)
30
 
    Bit8u  removable;    // Removable device flag
31
 
    Bit8u  lock;         // Locks for removable devices
32
 
    Bit16u blksize;      // block size
33
 
    chs_t  lchs;         // Logical CHS
34
 
    chs_t  pchs;         // Physical CHS
35
 
    Bit32u cSectors;     // Total sectors count
36
 
    Bit8u  port;         // Port this device is on.
37
 
} ahci_device_t;
 
41
    uint32_t    phys_addr;
 
42
    uint32_t    something;
 
43
    uint32_t    reserved;
 
44
    uint32_t    len;
 
45
} ahci_prdt;
38
46
 
39
47
/**
40
48
 * AHCI controller data.
45
53
     *  Because the BIOS doesn't support NCQ only the first command header is defined
46
54
     *  to save memory. - Must be aligned on a 1K boundary.
47
55
     */
48
 
    Bit32u        abCmdHdr[0x8];
 
56
    uint32_t        aCmdHdr[0x8];
49
57
    /** Align the next structure on a 128 byte boundary. */
50
 
    Bit8u         abAlignment1[0x60];
 
58
    uint8_t         abAlignment1[0x60];
51
59
    /** The command table of one request as defined by chapter 4.2.3 of the Intel AHCI spec.
52
60
     *  Must be aligned on 128 byte boundary.
53
61
     */
54
 
    Bit8u         abCmd[0x90];
55
 
    /** Alignment */
56
 
    Bit8u         abAlignment2[0xF0];
 
62
    uint8_t         abCmd[0x40];
 
63
    /** The ATAPI command region.
 
64
     *  Located 40h bytes after the beginning of the CFIS (Command FIS).
 
65
     */
 
66
    uint8_t         abAcmd[0x20];
 
67
    /** Align the PRDT structure on a 128 byte boundary. */
 
68
    uint8_t         abAlignment2[0x20];
 
69
    /** Physical Region Descriptor Table (PRDT) array. In other
 
70
     *  words, a scatter/gather descriptor list.
 
71
     */
 
72
    ahci_prdt       aPrdt[16];
57
73
    /** Memory for the received command FIS area as specified by chapter 4.2.1
58
74
     *  of the Intel AHCI spec. This area is normally 256 bytes big but to save memory
59
75
     *  only the first 96 bytes are used because it is assumed that the controller
60
76
     *  never writes to the UFIS or reserved area. - Must be aligned on a 256byte boundary.
61
77
     */
62
 
    Bit8u         abFisRecv[0x60];
 
78
    uint8_t         abFisRecv[0x60];
63
79
    /** Base I/O port for the index/data register pair. */
64
 
    Bit16u        iobase;
 
80
    uint16_t        iobase;
65
81
    /** Current port which uses the memory to communicate with the controller. */
66
 
    Bit8u         port;
67
 
    /** AHCI device information. */
68
 
    ahci_device_t aDevices[AHCI_MAX_STORAGE_DEVICES];
69
 
    /** Index of the next unoccupied device slot. */
70
 
    Bit8u         cDevices;
71
 
    /** Map between (bios hd id - 0x80) and ahci devices. */
72
 
    Bit8u         cHardDisks;
73
 
    Bit8u         aHdIdMap[AHCI_MAX_STORAGE_DEVICES];
74
 
    /** Map between (bios cd id - 0xE0) and ahci_devices. */
75
 
    Bit8u         cCdDrives;
76
 
    Bit8u         aCdIdMap[AHCI_MAX_STORAGE_DEVICES];
77
 
    /** int13 handler to call if given device is not from AHCI. */
78
 
    Bit16u        pfnInt13Old;
79
 
    /** Number of harddisks detected before the AHCI driver started detection. */
80
 
    Bit8u         cHardDisksOld;
 
82
    uint8_t         cur_port;
 
83
    /** Current PRD index (for pre/post skip). */
 
84
    uint8_t         cur_prd;
 
85
    /** Physical address of the sink buffer (for pre/post skip). */
 
86
    uint32_t        sink_buf_phys;
 
87
    /** Saved high bits of EAX. */
 
88
    uint16_t        saved_eax_hi;
 
89
    /** VDS EDDS DMA buffer descriptor structure. */
 
90
    vds_edds        edds;
 
91
    vds_sg          edds_more_sg[NUM_EDDS_SG - 1];
81
92
} ahci_t;
82
93
 
83
 
#define AhciData ((ahci_t *) 0)
84
 
 
85
 
/** Supported methods of the PCI BIOS. */
86
 
#define PCIBIOS_ID                      0xb1
87
 
#define PCIBIOS_PCI_BIOS_PRESENT        0x01
88
 
#define PCIBIOS_FIND_PCI_DEVICE         0x02
89
 
#define PCIBIOS_FIND_CLASS_CODE         0x03
90
 
#define PCIBIOS_GENERATE_SPECIAL_CYCLE  0x06
91
 
#define PCIBIOS_READ_CONFIG_BYTE        0x08
92
 
#define PCIBIOS_READ_CONFIG_WORD        0x09
93
 
#define PCIBIOS_READ_CONFIG_DWORD       0x0a
94
 
#define PCIBIOS_WRITE_CONFIG_BYTE       0x0b
95
 
#define PCIBIOS_WRITE_CONFIG_WORD       0x0c
96
 
#define PCIBIOS_WRITE_CONFIG_DWORD      0x0d
97
 
#define PCIBIOS_GET_IRQ_ROUTING_OPTIONS 0x0e
98
 
#define PCIBIOS_SET_PCI_IRQ             0x0f
99
 
 
100
 
/** Status codes. */
101
 
#define SUCCESSFUL                      0x00
102
 
#define FUNC_NOT_SUPPORTED              0x81
103
 
#define BAD_VENDOR_ID                   0x83
104
 
#define DEVICE_NOT_FOUND                0x86
105
 
#define BAD_REGISTER_NUMBER             0x87
106
 
#define SET_FAILED                      0x88
107
 
#define BUFFER_TOO_SMALL                0x89
 
94
/* The AHCI specific data must fit into 1KB (statically allocated). */
 
95
ct_assert(sizeof(ahci_t) <= 1024);
108
96
 
109
97
/** PCI configuration fields. */
110
98
#define PCI_CONFIG_CAP                  0x34
112
100
#define PCI_CAP_ID_SATACR               0x12
113
101
#define VBOX_AHCI_NO_DEVICE 0xffff
114
102
 
115
 
//#define VBOX_AHCI_DEBUG 1
116
 
//#define VBOX_AHCI_INT13_DEBUG 1
117
 
 
118
 
#ifdef VBOX_AHCI_DEBUG
119
 
# define VBOXAHCI_DEBUG(a...) BX_INFO(a)
120
 
#else
121
 
# define VBOXAHCI_DEBUG(a...)
122
 
#endif
123
 
 
124
 
#ifdef VBOX_AHCI_INT13_DEBUG
125
 
# define VBOXAHCI_INT13_DEBUG(a...) BX_INFO(a)
126
 
#else
127
 
# define VBOXAHCI_INT13_DEBUG(a...)
128
 
#endif
129
 
 
130
 
#define RT_BIT_32(bit) ((Bit32u)(1L << (bit)))
 
103
#define RT_BIT_32(bit) ((uint32_t)(1L << (bit)))
131
104
 
132
105
/** Global register set. */
133
106
#define AHCI_HBA_SIZE 0x100
134
107
 
135
 
#define AHCI_REG_CAP ((Bit32u)0x00)
136
 
#define AHCI_REG_GHC ((Bit32u)0x04)
 
108
//@todo: what are the casts good for?
 
109
#define AHCI_REG_CAP ((uint32_t)0x00)
 
110
#define AHCI_REG_GHC ((uint32_t)0x04)
137
111
# define AHCI_GHC_AE RT_BIT_32(31)
138
112
# define AHCI_GHC_IR RT_BIT_32(1)
139
113
# define AHCI_GHC_HR RT_BIT_32(0)
140
 
#define AHCI_REG_IS  ((Bit32u)0x08)
141
 
#define AHCI_REG_PI  ((Bit32u)0x0c)
142
 
#define AHCI_REG_VS  ((Bit32u)0x10)
 
114
#define AHCI_REG_IS  ((uint32_t)0x08)
 
115
#define AHCI_REG_PI  ((uint32_t)0x0c)
 
116
#define AHCI_REG_VS  ((uint32_t)0x10)
143
117
 
144
118
/** Per port register set. */
145
119
#define AHCI_PORT_SIZE     0x80
150
124
#define AHCI_REG_PORT_FBU  0x0c
151
125
#define AHCI_REG_PORT_IS   0x10
152
126
# define AHCI_REG_PORT_IS_DHRS RT_BIT_32(0)
 
127
# define AHCI_REG_PORT_IS_TFES RT_BIT_32(30)
153
128
#define AHCI_REG_PORT_IE   0x14
154
129
#define AHCI_REG_PORT_CMD  0x18
155
130
# define AHCI_REG_PORT_CMD_ST  RT_BIT_32(0)
165
140
#define AHCI_REG_PORT_CI   0x38
166
141
 
167
142
/** Returns the absolute register offset from a given port and port register. */
168
 
#define VBOXAHCI_PORT_REG(port, reg) ((Bit32u)(AHCI_HBA_SIZE + (port) * AHCI_PORT_SIZE + (reg)))
 
143
#define AHCI_PORT_REG(port, reg)    (AHCI_HBA_SIZE + (port) * AHCI_PORT_SIZE + (reg))
169
144
 
170
 
#define VBOXAHCI_REG_IDX   0
171
 
#define VBOXAHCI_REG_DATA  4
 
145
#define AHCI_REG_IDX   0
 
146
#define AHCI_REG_DATA  4
172
147
 
173
148
/** Writes the given value to a AHCI register. */
174
 
#define VBOXAHCI_WRITE_REG(iobase, reg, val) \
175
 
    outl((iobase) + VBOXAHCI_REG_IDX, (Bit32u)(reg)); \
176
 
    outl((iobase) + VBOXAHCI_REG_DATA, (Bit32u)(val))
 
149
#define AHCI_WRITE_REG(iobase, reg, val)    \
 
150
    outpd((iobase) + AHCI_REG_IDX, reg);    \
 
151
    outpd((iobase) + AHCI_REG_DATA, val)
177
152
 
178
153
/** Reads from a AHCI register. */
179
 
#define VBOXAHCI_READ_REG(iobase, reg, val) \
180
 
    outl((iobase) + VBOXAHCI_REG_IDX, (Bit32u)(reg)); \
181
 
    (val) = inl((iobase) + VBOXAHCI_REG_DATA)
 
154
#define AHCI_READ_REG(iobase, reg, val)     \
 
155
    outpd((iobase) + AHCI_REG_IDX, reg);    \
 
156
    (val) = inpd((iobase) + AHCI_REG_DATA)
182
157
 
183
158
/** Writes to the given port register. */
184
 
#define VBOXAHCI_PORT_WRITE_REG(iobase, port, reg, val) \
185
 
    VBOXAHCI_WRITE_REG((iobase), VBOXAHCI_PORT_REG((port), (reg)), val)
 
159
#define VBOXAHCI_PORT_WRITE_REG(iobase, port, reg, val)     \
 
160
    AHCI_WRITE_REG((iobase), AHCI_PORT_REG((port), (reg)), val)
186
161
 
187
162
/** Reads from the given port register. */
188
 
#define VBOXAHCI_PORT_READ_REG(iobase, port, reg, val) \
189
 
    VBOXAHCI_READ_REG((iobase), VBOXAHCI_PORT_REG((port), (reg)), val)
190
 
 
191
 
#define ATA_CMD_IDENTIFY_DEVICE 0xEC
192
 
#define AHCI_CMD_READ_DMA_EXT 0x25
193
 
#define AHCI_CMD_WRITE_DMA_EXT 0x35
194
 
 
195
 
/**
196
 
 * Returns the bus/device/function of a PCI device with
197
 
 * the given classcode.
198
 
 *
199
 
 * @returns bus/device/fn in one 16bit integer where
200
 
 *          where the upper byte contains the bus number
201
 
 *          and lower one the device and function number.
202
 
 *          VBOX_AHCI_NO_DEVICE if no device was found.
203
 
 * @param   u16Class    The classcode to search for.
204
 
 */
205
 
Bit16u ahci_pci_find_classcode(u16Class)
206
 
    Bit32u u16Class;
207
 
{
208
 
    Bit16u u16BusDevFn;
209
 
 
210
 
ASM_START
211
 
    push bp
212
 
    mov  bp, sp
213
 
 
214
 
    mov ah, #PCIBIOS_ID
215
 
    mov al, #PCIBIOS_FIND_CLASS_CODE
216
 
    mov ecx, _ahci_pci_find_classcode.u16Class + 2[bp]
217
 
    mov si, #0                                    ; First controller
218
 
    int 0x1a
219
 
 
220
 
    ; Return from PCIBIOS
221
 
    cmp ah, #SUCCESSFUL
222
 
    jne ahci_pci_find_classcode_not_found
223
 
 
224
 
    mov _ahci_pci_find_classcode.u16BusDevFn + 2[bp], bx
225
 
    jmp ahci_pci_find_classcode_done
226
 
 
227
 
ahci_pci_find_classcode_not_found:
228
 
    mov _ahci_pci_find_classcode.u16BusDevFn + 2[bp], #VBOX_AHCI_NO_DEVICE
229
 
 
230
 
ahci_pci_find_classcode_done:
231
 
    pop bp
232
 
ASM_END
233
 
 
234
 
    return u16BusDevFn;
235
 
}
236
 
 
237
 
Bit8u ahci_pci_read_config_byte(u8Bus, u8DevFn, u8Reg)
238
 
    Bit8u u8Bus, u8DevFn, u8Reg;
239
 
{
240
 
    Bit8u u8Val;
241
 
 
242
 
    u8Val = 0;
243
 
 
244
 
ASM_START
245
 
    push bp
246
 
    mov  bp, sp
247
 
 
248
 
    mov ah, #PCIBIOS_ID
249
 
    mov al, #PCIBIOS_READ_CONFIG_BYTE
250
 
    mov bh, _ahci_pci_read_config_byte.u8Bus + 2[bp]
251
 
    mov bl, _ahci_pci_read_config_byte.u8DevFn + 2[bp]
252
 
    mov di, _ahci_pci_read_config_byte.u8Reg + 2[bp]
253
 
    int 0x1a
254
 
 
255
 
    ; Return from PCIBIOS
256
 
    cmp ah, #SUCCESSFUL
257
 
    jne ahci_pci_read_config_byte_done
258
 
 
259
 
    mov _ahci_pci_read_config_byte.u8Val + 2[bp], cl
260
 
 
261
 
ahci_pci_read_config_byte_done:
262
 
    pop bp
263
 
ASM_END
264
 
 
265
 
    return u8Val;
266
 
}
267
 
 
268
 
Bit16u ahci_pci_read_config_word(u8Bus, u8DevFn, u8Reg)
269
 
    Bit8u u8Bus, u8DevFn, u8Reg;
270
 
{
271
 
    Bit16u u16Val;
272
 
 
273
 
    u16Val = 0;
274
 
 
275
 
ASM_START
276
 
    push bp
277
 
    mov  bp, sp
278
 
 
279
 
    mov ah, #PCIBIOS_ID
280
 
    mov al, #PCIBIOS_READ_CONFIG_WORD
281
 
    mov bh, _ahci_pci_read_config_word.u8Bus + 2[bp]
282
 
    mov bl, _ahci_pci_read_config_word.u8DevFn + 2[bp]
283
 
    mov di, _ahci_pci_read_config_word.u8Reg + 2[bp]
284
 
    int 0x1a
285
 
 
286
 
    ; Return from PCIBIOS
287
 
    cmp ah, #SUCCESSFUL
288
 
    jne ahci_pci_read_config_word_done
289
 
 
290
 
    mov _ahci_pci_read_config_word.u16Val + 2[bp], cx
291
 
 
292
 
ahci_pci_read_config_word_done:
293
 
    pop bp
294
 
ASM_END
295
 
 
296
 
    return u16Val;
297
 
}
298
 
 
299
 
Bit32u ahci_pci_read_config_dword(u8Bus, u8DevFn, u8Reg)
300
 
    Bit8u u8Bus, u8DevFn, u8Reg;
301
 
{
302
 
    Bit32u u32Val;
303
 
 
304
 
    u32Val = 0;
305
 
 
306
 
ASM_START
307
 
    push bp
308
 
    mov  bp, sp
309
 
 
310
 
    mov ah, #PCIBIOS_ID
311
 
    mov al, #PCIBIOS_READ_CONFIG_DWORD
312
 
    mov bh, _ahci_pci_read_config_dword.u8Bus + 2[bp]
313
 
    mov bl, _ahci_pci_read_config_dword.u8DevFn + 2[bp]
314
 
    mov di, _ahci_pci_read_config_dword.u8Reg + 2[bp]
315
 
    int 0x1a
316
 
 
317
 
    ; Return from PCIBIOS
318
 
    cmp ah, #SUCCESSFUL
319
 
    jne ahci_pci_read_config_dword_done
320
 
 
321
 
    mov _ahci_pci_read_config_dword.u32Val + 2[bp], ecx
322
 
 
323
 
ahci_pci_read_config_dword_done:
324
 
    pop bp
325
 
ASM_END
326
 
 
327
 
    return u32Val;
328
 
}
329
 
 
330
 
#if 0 /* Disabled to save space because they are not needed. Might become useful in the future. */
331
 
/**
332
 
 * Returns the bus/device/function of a PCI device with
333
 
 * the given vendor and device id.
334
 
 *
335
 
 * @returns bus/device/fn in one 16bit integer where
336
 
 *          where the upper byte contains the bus number
337
 
 *          and lower one the device and function number.
338
 
 *          VBOX_AHCI_NO_DEVICE if no device was found.
339
 
 * @param   u16Vendor    The vendor ID.
340
 
 * @param   u16Device    The device ID.
341
 
 */
342
 
Bit16u ahci_pci_find_device(u16Vendor, u16Device)
343
 
    Bit16u u16Vendor;
344
 
    Bit16u u16Device;
345
 
{
346
 
    Bit16u u16BusDevFn;
347
 
 
348
 
ASM_START
349
 
    push bp
350
 
    mov  bp, sp
351
 
 
352
 
    mov ah, #PCIBIOS_ID
353
 
    mov al, #PCIBIOS_FIND_PCI_DEVICE
354
 
    mov cx, _ahci_pci_find_device.u16Device + 2[bp]
355
 
    mov dx, _ahci_pci_find_device.u16Vendor + 2[bp]
356
 
    mov si, #0                                    ; First controller
357
 
    int 0x1a
358
 
 
359
 
    ; Return from PCIBIOS
360
 
    cmp ah, #SUCCESSFUL
361
 
    jne ahci_pci_find_device_not_found
362
 
 
363
 
    mov _ahci_pci_find_device.u16BusDevFn + 2[bp], bx
364
 
    jmp ahci_pci_find_device_done
365
 
 
366
 
ahci_pci_find_device_not_found:
367
 
    mov _ahci_pci_find_device.u16BusDevFn + 2[bp], #VBOX_AHCI_NO_DEVICE
368
 
 
369
 
ahci_pci_find_device_done:
370
 
    pop bp
371
 
ASM_END
372
 
 
373
 
    return u16BusDevFn;
374
 
}
375
 
 
376
 
void ahci_pci_write_config_byte(u8Bus, u8DevFn, u8Reg, u8Val)
377
 
    Bit8u u8Bus, u8DevFn, u8Reg, u8Val;
378
 
{
379
 
ASM_START
380
 
    push bp
381
 
    mov  bp, sp
382
 
 
383
 
    mov ah, #PCIBIOS_ID
384
 
    mov al, #PCIBIOS_WRITE_CONFIG_BYTE
385
 
    mov bh, _ahci_pci_write_config_byte.u8Bus + 2[bp]
386
 
    mov bl, _ahci_pci_write_config_byte.u8DevFn + 2[bp]
387
 
    mov di, _ahci_pci_write_config_byte.u8Reg + 2[bp]
388
 
    mov cl, _ahci_pci_write_config_byte.u8Val + 2[bp]
389
 
    int 0x1a
390
 
 
391
 
    ; Return from PCIBIOS
392
 
    pop bp
393
 
ASM_END
394
 
}
395
 
 
396
 
void ahci_pci_write_config_word(u8Bus, u8DevFn, u8Reg, u16Val)
397
 
    Bit8u u8Bus, u8DevFn, u8Reg;
398
 
    Bit16u u16Val;
399
 
{
400
 
ASM_START
401
 
    push bp
402
 
    mov  bp, sp
403
 
 
404
 
    mov ah, #PCIBIOS_ID
405
 
    mov al, #PCIBIOS_WRITE_CONFIG_WORD
406
 
    mov bh, _ahci_pci_write_config_word.u8Bus + 2[bp]
407
 
    mov bl, _ahci_pci_write_config_word.u8DevFn + 2[bp]
408
 
    mov di, _ahci_pci_write_config_word.u8Reg + 2[bp]
409
 
    mov cx, _ahci_pci_write_config_word.u16Val + 2[bp]
410
 
    int 0x1a
411
 
 
412
 
    ; Return from PCIBIOS
413
 
    pop bp
414
 
ASM_END
415
 
}
416
 
 
417
 
void ahci_pci_write_config_dword(u8Bus, u8DevFn, u8Reg, u32Val)
418
 
    Bit8u u8Bus, u8DevFn, u8Reg;
419
 
    Bit32u u32Val;
420
 
{
421
 
ASM_START
422
 
    push bp
423
 
    mov  bp, sp
424
 
 
425
 
    mov ah, #PCIBIOS_ID
426
 
    mov al, #PCIBIOS_WRITE_CONFIG_WORD
427
 
    mov bh, _ahci_pci_write_config_dword.u8Bus + 2[bp]
428
 
    mov bl, _ahci_pci_write_config_dword.u8DevFn + 2[bp]
429
 
    mov di, _ahci_pci_write_config_dword.u8Reg + 2[bp]
430
 
    mov cx, _ahci_pci_write_config_dword.u32Val + 2[bp]
431
 
    int 0x1a
432
 
 
433
 
    ; Return from PCIBIOS
434
 
    pop bp
435
 
ASM_END
436
 
}
437
 
#endif /* 0 */
 
163
#define VBOXAHCI_PORT_READ_REG(iobase, port, reg, val)      \
 
164
    AHCI_READ_REG((iobase), AHCI_PORT_REG((port), (reg)), val)
 
165
 
 
166
#define ATA_CMD_IDENTIFY_DEVICE     0xEC
 
167
#define ATA_CMD_IDENTIFY_PACKET     0xA1
 
168
#define ATA_CMD_PACKET              0xA0
 
169
#define AHCI_CMD_READ_DMA_EXT       0x25
 
170
#define AHCI_CMD_WRITE_DMA_EXT      0x35
 
171
 
 
172
 
 
173
/* Warning: Destroys high bits of EAX. */
 
174
uint32_t inpd(uint16_t port);
 
175
#pragma aux inpd =      \
 
176
    ".386"              \
 
177
    "in     eax, dx"    \
 
178
    "mov    dx, ax"     \
 
179
    "shr    eax, 16"    \
 
180
    "xchg   ax, dx"     \
 
181
    parm [dx] value [dx ax] modify nomemory;
 
182
 
 
183
/* Warning: Destroys high bits of EAX. */
 
184
void outpd(uint16_t port, uint32_t val);
 
185
#pragma aux outpd =     \
 
186
    ".386"              \
 
187
    "xchg   ax, cx"     \
 
188
    "shl    eax, 16"    \
 
189
    "mov    ax, cx"     \
 
190
    "out    dx, eax"    \
 
191
    parm [dx] [cx ax] modify nomemory;
 
192
 
 
193
 
 
194
/* Machinery to save/restore high bits of EAX. 32-bit port I/O needs to use
 
195
 * EAX, but saving/restoring EAX around each port access would be inefficient.
 
196
 * Instead, each externally callable routine must save the high bits before
 
197
 * modifying them and restore the high bits before exiting.
 
198
 */
 
199
 
 
200
/* Note: Reading high EAX bits destroys them - *must* be restored later. */
 
201
uint16_t eax_hi_rd(void);
 
202
#pragma aux eax_hi_rd = \
 
203
    ".386"              \
 
204
    "shr    eax, 16"    \
 
205
    value [ax] modify nomemory;
 
206
 
 
207
void eax_hi_wr(uint16_t);
 
208
#pragma aux eax_hi_wr = \
 
209
    ".386"              \
 
210
    "shl    eax, 16"    \
 
211
    parm [ax] modify nomemory;
 
212
 
 
213
void high_bits_save(ahci_t __far *ahci)
 
214
{
 
215
    ahci->saved_eax_hi = eax_hi_rd();
 
216
}
 
217
 
 
218
void high_bits_restore(ahci_t __far *ahci)
 
219
{
 
220
    eax_hi_wr(ahci->saved_eax_hi);
 
221
}
438
222
 
439
223
/**
440
224
 * Sets a given set of bits in a register.
441
225
 */
442
 
static void ahci_ctrl_set_bits(u16IoBase, u32Reg, u32Set)
443
 
    Bit16u u16IoBase;
444
 
    Bit32u u32Reg, u32Set;
 
226
static void ahci_ctrl_set_bits(uint16_t iobase, uint16_t reg, uint32_t mask)
445
227
{
446
 
ASM_START
447
 
    push bp
448
 
    mov bp, sp
449
 
 
450
 
    push eax
451
 
    push edx
452
 
 
453
 
    ; Read from the register
454
 
    mov eax, _ahci_ctrl_set_bits.u32Reg + 2[bp]
455
 
    mov dx, _ahci_ctrl_set_bits.u16IoBase + 2[bp]
456
 
    add dx, #VBOXAHCI_REG_IDX
457
 
    out dx, eax
458
 
 
459
 
    mov dx, _ahci_ctrl_set_bits.u16IoBase + 2[bp]
460
 
    add dx, #VBOXAHCI_REG_DATA
461
 
    in eax, dx
462
 
 
463
 
    ; Set the new bits and write the result to the register again
464
 
    or eax, _ahci_ctrl_set_bits.u32Set + 2[bp]
465
 
    out dx, eax
466
 
 
467
 
    pop edx
468
 
    pop eax
469
 
 
470
 
    pop bp
471
 
ASM_END
 
228
    outpd(iobase + AHCI_REG_IDX, reg);
 
229
    outpd(iobase + AHCI_REG_DATA, inpd(iobase + AHCI_REG_DATA) | mask);
472
230
}
473
231
 
474
232
/**
475
233
 * Clears a given set of bits in a register.
476
234
 */
477
 
static void ahci_ctrl_clear_bits(u16IoBase, u32Reg, u32Clear)
478
 
    Bit16u u16IoBase;
479
 
    Bit32u u32Reg, u32Clear;
 
235
static void ahci_ctrl_clear_bits(uint16_t iobase, uint16_t reg, uint32_t mask)
480
236
{
481
 
ASM_START
482
 
    push bp
483
 
    mov bp, sp
484
 
 
485
 
    push eax
486
 
    push ecx
487
 
    push edx
488
 
 
489
 
    ; Read from the register
490
 
    mov eax, _ahci_ctrl_clear_bits.u32Reg + 2[bp]
491
 
    mov dx, _ahci_ctrl_clear_bits.u16IoBase + 2[bp]
492
 
    add dx, #VBOXAHCI_REG_IDX
493
 
    out dx, eax
494
 
 
495
 
    mov dx, _ahci_ctrl_clear_bits.u16IoBase + 2[bp]
496
 
    add dx, #VBOXAHCI_REG_DATA
497
 
    in eax, dx
498
 
 
499
 
    ; Clear the bits and write the result to the register again
500
 
    mov ecx, _ahci_ctrl_clear_bits.u32Clear + 2[bp]
501
 
    not ecx
502
 
    and eax, ecx
503
 
    out dx, eax
504
 
 
505
 
    pop edx
506
 
    pop ecx
507
 
    pop eax
508
 
 
509
 
    pop bp
510
 
ASM_END
 
237
    outpd(iobase + AHCI_REG_IDX, reg);
 
238
    outpd(iobase + AHCI_REG_DATA, inpd(iobase + AHCI_REG_DATA) & ~mask);
511
239
}
512
240
 
513
241
/**
514
242
 * Returns whether at least one of the bits in the given mask is set
515
243
 * for a register.
516
244
 */
517
 
static Bit8u ahci_ctrl_is_bit_set(u16IoBase, u32Reg, u32Mask)
518
 
    Bit16u u16IoBase;
519
 
    Bit32u u32Reg, u32Mask;
 
245
static uint8_t ahci_ctrl_is_bit_set(uint16_t iobase, uint16_t reg, uint32_t mask)
520
246
{
521
 
ASM_START
522
 
    push bp
523
 
    mov bp, sp
524
 
 
525
 
    push edx
526
 
    push eax
527
 
 
528
 
    ; Read from the register
529
 
    mov eax, _ahci_ctrl_is_bit_set.u32Reg + 2[bp]
530
 
    mov dx, _ahci_ctrl_is_bit_set.u16IoBase + 2[bp]
531
 
    add dx, #VBOXAHCI_REG_IDX
532
 
    out dx, eax
533
 
 
534
 
    mov dx, _ahci_ctrl_is_bit_set.u16IoBase + 2[bp]
535
 
    add dx, #VBOXAHCI_REG_DATA
536
 
    in eax, dx
537
 
 
538
 
    ; Check for set bits
539
 
    mov edx, _ahci_ctrl_is_bit_set.u32Mask + 2[bp]
540
 
    test eax, edx
541
 
    je ahci_ctrl_is_bit_set_not_set
542
 
    mov al, #1                                       ; At least one of the bits is set
543
 
    jmp ahci_ctrl_is_bit_set_done
544
 
 
545
 
ahci_ctrl_is_bit_set_not_set:
546
 
    mov al, #0                                       ; No bit is set
547
 
 
548
 
ahci_ctrl_is_bit_set_done:
549
 
    pop edx                                          ; restore upper 16 bits of eax
550
 
    and edx, #0xffff0000
551
 
    or  eax, edx
552
 
    pop edx
553
 
 
554
 
    pop bp
555
 
ASM_END
 
247
    outpd(iobase + AHCI_REG_IDX, reg);
 
248
    return (inpd(iobase + AHCI_REG_DATA) & mask) != 0;
556
249
}
557
250
 
558
251
/**
559
252
 * Extracts a range of bits from a register and shifts them
560
253
 * to the right.
561
254
 */
562
 
static Bit16u ahci_ctrl_extract_bits(u32Reg, u32Mask, u8Shift)
563
 
    Bit32u u32Reg, u32Mask, u8Shift;
 
255
static uint16_t ahci_ctrl_extract_bits(uint32_t val, uint32_t mask, uint8_t shift)
564
256
{
565
 
ASM_START
566
 
    push bp
567
 
    mov bp, sp
568
 
 
569
 
    push cx
570
 
 
571
 
    mov eax, _ahci_ctrl_extract_bits.u32Reg  + 2[bp]
572
 
    mov cl,  _ahci_ctrl_extract_bits.u8Shift + 2[bp]
573
 
    and eax, _ahci_ctrl_extract_bits.u32Mask + 2[bp]
574
 
    shr eax, cl
575
 
 
576
 
    pop cx
577
 
 
578
 
    pop bp
579
 
ASM_END
 
257
    return (val & mask) >> shift;
580
258
}
581
259
 
582
260
/**
583
261
 * Converts a segment:offset pair into a 32bit physical address.
584
262
 */
585
 
static Bit32u ahci_addr_to_phys(u16Segment, u16Offset)
586
 
    Bit16u u16Segment, u16Offset;
 
263
static uint32_t ahci_addr_to_phys(void __far *ptr)
587
264
{
588
 
ASM_START
589
 
    push bp
590
 
    mov bp, sp
591
 
 
592
 
    push bx
593
 
    push eax
594
 
 
595
 
    xor eax, eax
596
 
    xor ebx, ebx
597
 
    mov ax, _ahci_addr_to_phys.u16Segment + 2[bp]
598
 
    shl eax, #4
599
 
    add bx, _ahci_addr_to_phys.u16Offset + 2[bp]
600
 
    add eax, ebx
601
 
 
602
 
    mov bx, ax
603
 
    shr eax, #16
604
 
    mov dx, ax
605
 
 
606
 
    pop eax
607
 
    mov ax, bx
608
 
    pop bx
609
 
 
610
 
    pop bp
611
 
ASM_END
 
265
    return ((uint32_t)FP_SEG(ptr) << 4) + FP_OFF(ptr);
612
266
}
613
267
 
614
268
/**
615
269
 * Issues a command to the SATA controller and waits for completion.
616
270
 */
617
 
static void ahci_port_cmd_sync(SegAhci, u16IoBase, fWrite, fAtapi, cFisDWords, cbData)
618
 
    Bit16u SegAhci;
619
 
    Bit16u u16IoBase;
620
 
    bx_bool fWrite;
621
 
    bx_bool fAtapi;
622
 
    Bit8u   cFisDWords;
623
 
    Bit16u  cbData;
 
271
static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val)
624
272
{
625
 
    Bit8u u8Port;
626
 
 
627
 
    u8Port = read_byte(SegAhci, &AhciData->port);
628
 
 
629
 
    if (u8Port != 0xff)
 
273
    uint16_t        io_base;
 
274
    uint8_t         port;
 
275
 
 
276
    port    = ahci->cur_port;
 
277
    io_base = ahci->iobase;
 
278
 
 
279
    if (port != 0xff)
630
280
    {
631
 
        Bit32u u32Val;
632
 
 
633
281
        /* Prepare the command header. */
634
 
        u32Val = (1L << 16) | RT_BIT_32(7);
635
 
        if (fWrite)
636
 
            u32Val |= RT_BIT_32(6);
637
 
 
638
 
        if (fAtapi)
639
 
            u32Val |= RT_BIT_32(5);
640
 
 
641
 
        u32Val |= cFisDWords;
642
 
 
643
 
        write_dword(SegAhci, &AhciData->abCmdHdr[0], u32Val);
644
 
        write_dword(SegAhci, &AhciData->abCmdHdr[1], (Bit32u)cbData);
645
 
        write_dword(SegAhci, &AhciData->abCmdHdr[2],
646
 
                    ahci_addr_to_phys(SegAhci, &AhciData->abCmd[0]));
 
282
        ahci->aCmdHdr[0] = ((uint32_t)ahci->cur_prd << 16) | RT_BIT_32(7) | val;
 
283
        ahci->aCmdHdr[1] = 0;
 
284
        ahci->aCmdHdr[2] = ahci_addr_to_phys(&ahci->abCmd[0]);
647
285
 
648
286
        /* Enable Command and FIS receive engine. */
649
 
        ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
287
        ahci_ctrl_set_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
650
288
                           AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
651
289
 
652
290
        /* Queue command. */
653
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CI, 0x1L);
 
291
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_CI, 0x1);
654
292
 
655
 
        /* Wait for a D2H Fis. */
656
 
        while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_IS),
657
 
                                    AHCI_REG_PORT_IS_DHRS) == 0)
 
293
        /* Wait for a D2H FIS. */
 
294
        DBG_AHCI("AHCI: Waiting for D2H FIS\n");
 
295
        while (ahci_ctrl_is_bit_set(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_IS),
 
296
                                    AHCI_REG_PORT_IS_DHRS | AHCI_REG_PORT_IS_TFES) == 0)
658
297
        {
659
 
            VBOXAHCI_DEBUG("AHCI: Waiting for a D2H Fis\n");
 
298
            // This is where we'd need some kind of a yield functionality...
660
299
        }
661
300
 
662
 
        ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_IS),
 
301
        ahci_ctrl_set_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_IS),
663
302
                           AHCI_REG_PORT_IS_DHRS); /* Acknowledge received D2H FIS. */
664
303
 
665
304
        /* Disable command engine. */
666
 
        ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
305
        ahci_ctrl_clear_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
667
306
                             AHCI_REG_PORT_CMD_ST);
668
307
 
669
308
        /** @todo: Examine status. */
670
309
    }
671
310
    else
672
 
        VBOXAHCI_DEBUG("AHCI: Invalid port given\n");
 
311
        DBG_AHCI("AHCI: Invalid port given\n");
673
312
}
674
313
 
675
314
/**
676
315
 * Issue command to device.
677
316
 */
678
 
static void ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, u8Feat, u8Device, u8CylHigh, u8CylLow, u8Sect,
679
 
                          u8FeatExp, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp,
680
 
                          SegData, OffData, cbData, fWrite)
681
 
    Bit16u SegAhci;
682
 
    Bit16u u16IoBase;
683
 
    Bit8u  u8Cmd, u8Feat, u8Device, u8CylHigh, u8CylLow, u8Sect, u8FeatExp,
684
 
           u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
685
 
    Bit16u SegData, OffData, cbData;
686
 
    bx_bool fWrite;
 
317
static void ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
687
318
{
688
 
    memsetb(SegAhci, &AhciData->abCmd[0], 0, sizeof(AhciData->abCmd));
 
319
    ahci_t __far    *ahci  = bios_dsk->ahci_seg :> 0;
 
320
    uint16_t        n_sect = bios_dsk->drqp.nsect;
 
321
    uint16_t        sectsz = bios_dsk->drqp.sect_sz;
 
322
    uint16_t        prdt_idx;
 
323
 
 
324
    _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
689
325
 
690
326
    /* Prepare the FIS. */
691
 
    write_byte(SegAhci, &AhciData->abCmd[0], 0x27);   /* FIS type H2D. */
692
 
    write_byte(SegAhci, &AhciData->abCmd[1], 1 << 7); /* Command update. */
693
 
    write_byte(SegAhci, &AhciData->abCmd[2], u8Cmd);
694
 
    write_byte(SegAhci, &AhciData->abCmd[3], u8Feat);
695
 
 
696
 
    write_byte(SegAhci, &AhciData->abCmd[4], u8Sect);
697
 
    write_byte(SegAhci, &AhciData->abCmd[5], u8CylLow);
698
 
    write_byte(SegAhci, &AhciData->abCmd[6], u8CylHigh);
699
 
    write_byte(SegAhci, &AhciData->abCmd[7], u8Device);
700
 
 
701
 
    write_byte(SegAhci, &AhciData->abCmd[8], u8SectExp);
702
 
    write_byte(SegAhci, &AhciData->abCmd[9], u8CylLowExp);
703
 
    write_byte(SegAhci, &AhciData->abCmd[10], u8CylHighExp);
704
 
    write_byte(SegAhci, &AhciData->abCmd[11], u8FeatExp);
705
 
 
706
 
    write_byte(SegAhci, &AhciData->abCmd[12], u8SectCount);
707
 
    write_byte(SegAhci, &AhciData->abCmd[13], u8SectCountExp);
708
 
 
709
 
    /* Prepare PRDT. */
710
 
    write_dword(SegAhci, &AhciData->abCmd[0x80], ahci_addr_to_phys(SegData, OffData));
711
 
    write_dword(SegAhci, &AhciData->abCmd[0x8c], (Bit32u)(cbData - 1));
712
 
 
713
 
    ahci_port_cmd_sync(SegAhci, u16IoBase, fWrite, 0, 5, cbData);
 
327
    ahci->abCmd[0]  = 0x27;         /* FIS type H2D. */
 
328
    ahci->abCmd[1]  = 1 << 7;       /* Command update. */
 
329
    ahci->abCmd[2]  = cmd;
 
330
    ahci->abCmd[3]  = 0;
 
331
 
 
332
    ahci->abCmd[4]  = bios_dsk->drqp.lba & 0xff;
 
333
    ahci->abCmd[5]  = (bios_dsk->drqp.lba >> 8) & 0xff;
 
334
    ahci->abCmd[6]  = (bios_dsk->drqp.lba >> 16) & 0xff;
 
335
    ahci->abCmd[7]  = RT_BIT_32(6); /* LBA access. */
 
336
 
 
337
    ahci->abCmd[8]  = (bios_dsk->drqp.lba >> 24) & 0xff;
 
338
    ahci->abCmd[9]  = 0;
 
339
    ahci->abCmd[10] = 0;
 
340
    ahci->abCmd[11] = 0;
 
341
 
 
342
    ahci->abCmd[12] = (uint8_t)(n_sect & 0xff);
 
343
    ahci->abCmd[13] = (uint8_t)((n_sect >> 8) & 0xff);
 
344
 
 
345
    /* Lock memory needed for DMA. */
 
346
    ahci->edds.num_avail = NUM_EDDS_SG;
 
347
    DBG_AHCI("AHCI: S/G list for %lu bytes (skip %u)\n", 
 
348
             (uint32_t)n_sect * sectsz, bios_dsk->drqp.skip_a);
 
349
    vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz);
 
350
 
 
351
    prdt_idx = ahci->cur_prd;
 
352
 
 
353
    /* Set up the PRDT. */
 
354
    ahci->aPrdt[prdt_idx].len       = ahci->edds.u.sg[0].size - 1;
 
355
    ahci->aPrdt[prdt_idx].phys_addr = ahci->edds.u.sg[0].phys_addr;
 
356
    ++prdt_idx;
 
357
 
 
358
    if (bios_dsk->drqp.skip_a) {
 
359
        ahci->aPrdt[prdt_idx].len       = bios_dsk->drqp.skip_a - 1;
 
360
        ahci->aPrdt[prdt_idx].phys_addr = ahci->sink_buf_phys;
 
361
        ++prdt_idx;
 
362
    }
 
363
 
 
364
    ahci->cur_prd = prdt_idx;
 
365
 
 
366
#ifdef DEBUG_AHCI
 
367
    for (prdt_idx = 0; prdt_idx < ahci->cur_prd; ++prdt_idx) {
 
368
        DBG_AHCI("S/G entry %u: %5lu bytes @ %08lX\n", prdt_idx,
 
369
                 ahci->aPrdt[prdt_idx].len + 1, ahci->aPrdt[prdt_idx].phys_addr);
 
370
    }
 
371
#endif
 
372
 
 
373
    /* Build variable part of first command DWORD (reuses 'cmd'). */
 
374
    if (cmd == AHCI_CMD_WRITE_DMA_EXT)
 
375
        cmd = RT_BIT_32(6);     /* Indicate a write to device. */
 
376
    else if (cmd == ATA_CMD_PACKET) {
 
377
        cmd |= RT_BIT_32(5);    /* Indicate ATAPI command. */
 
378
        ahci->abCmd[3] |= 1;    /* DMA transfers. */
 
379
    } else
 
380
        cmd = 0;
 
381
 
 
382
    cmd |= 5;   /* Five DWORDs. */
 
383
 
 
384
    ahci_port_cmd_sync(ahci, cmd);
 
385
 
 
386
    /* Unlock the buffer again. */
 
387
    vds_free_sg_list(&ahci->edds);
714
388
}
715
389
 
716
390
/**
717
391
 * Deinits the curent active port.
718
392
 */
719
 
static void ahci_port_deinit_current(SegAhci, u16IoBase)
720
 
    Bit16u SegAhci;
721
 
    Bit16u u16IoBase;
 
393
static void ahci_port_deinit_current(ahci_t __far *ahci)
722
394
{
723
 
    Bit8u u8Port;
724
 
 
725
 
    u8Port = read_byte(SegAhci, &AhciData->port);
726
 
 
727
 
    if (u8Port != 0xff)
 
395
    uint16_t    io_base;
 
396
    uint8_t     port;
 
397
 
 
398
    io_base = ahci->iobase;
 
399
    port    = ahci->cur_port;
 
400
 
 
401
    if (port != 0xff)
728
402
    {
729
403
        /* Put the port into an idle state. */
730
 
        ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
404
        ahci_ctrl_clear_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
731
405
                             AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
732
406
 
733
 
        while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
407
        while (ahci_ctrl_is_bit_set(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
734
408
                                    AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST | AHCI_REG_PORT_CMD_FR | AHCI_REG_PORT_CMD_CR) == 1)
735
409
        {
736
 
            VBOXAHCI_DEBUG("AHCI: Waiting for the port to idle\n");
 
410
            DBG_AHCI("AHCI: Waiting for the port to idle\n");
737
411
        }
738
412
 
739
413
        /*
740
414
         * Port idles, set up memory for commands and received FIS and program the
741
415
         * address registers.
742
416
         */
743
 
        memsetb(SegAhci, &AhciData->abFisRecv[0], 0, 0x60);
744
 
        memsetb(SegAhci, &AhciData->abCmdHdr[0], 0, 0x20);
745
 
        memsetb(SegAhci, &AhciData->abCmd[0], 0, 0x84);
746
 
 
747
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FB, 0L);
748
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FBU, 0L);
749
 
 
750
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLB, 0L);
751
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLBU, 0L);
 
417
        //@todo: merge memsets?
 
418
        _fmemset(&ahci->aCmdHdr[0], 0, sizeof(ahci->aCmdHdr));
 
419
        _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
 
420
        _fmemset(&ahci->abFisRecv[0], 0, sizeof(ahci->abFisRecv));
 
421
 
 
422
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_FB, 0);
 
423
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_FBU, 0);
 
424
 
 
425
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_CLB, 0);
 
426
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_CLBU, 0);
752
427
 
753
428
        /* Disable all interrupts. */
754
 
        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0L);
 
429
        VBOXAHCI_PORT_WRITE_REG(io_base, port, AHCI_REG_PORT_IE, 0);
755
430
 
756
 
        write_byte(SegAhci, &AhciData->port, 0xff);
 
431
        ahci->cur_port = 0xff;
757
432
    }
758
433
}
759
434
 
761
436
 * Brings a port into a minimal state to make device detection possible
762
437
 * or to queue requests.
763
438
 */
764
 
static void ahci_port_init(SegAhci, u16IoBase, u8Port)
765
 
    Bit16u SegAhci;
766
 
    Bit16u u16IoBase;
767
 
    Bit8u u8Port;
 
439
static void ahci_port_init(ahci_t __far *ahci, uint8_t u8Port)
768
440
{
769
 
    Bit32u u32PhysAddr;
770
 
 
771
441
    /* Deinit any other port first. */
772
 
    ahci_port_deinit_current(SegAhci, u16IoBase);
 
442
    ahci_port_deinit_current(ahci);
773
443
 
774
444
    /* Put the port into an idle state. */
775
 
    ahci_ctrl_clear_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
445
    ahci_ctrl_clear_bits(ahci->iobase, AHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
776
446
                         AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST);
777
447
 
778
 
    while (ahci_ctrl_is_bit_set(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
448
    while (ahci_ctrl_is_bit_set(ahci->iobase, AHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
779
449
                                AHCI_REG_PORT_CMD_FRE | AHCI_REG_PORT_CMD_ST | AHCI_REG_PORT_CMD_FR | AHCI_REG_PORT_CMD_CR) == 1)
780
450
    {
781
 
        VBOXAHCI_DEBUG("AHCI: Waiting for the port to idle\n");
 
451
        DBG_AHCI("AHCI: Waiting for the port to idle\n");
782
452
    }
783
453
 
784
454
    /*
785
455
     * Port idles, set up memory for commands and received FIS and program the
786
456
     * address registers.
787
457
     */
788
 
    memsetb(SegAhci, &AhciData->abFisRecv[0], 0, 0x60);
789
 
    memsetb(SegAhci, &AhciData->abCmdHdr[0], 0, 0x20);
790
 
    memsetb(SegAhci, &AhciData->abCmd[0], 0, 0x84);
791
 
 
792
 
    u32PhysAddr = ahci_addr_to_phys(SegAhci, &AhciData->abFisRecv);
793
 
    VBOXAHCI_DEBUG("AHCI: FIS receive area %lx from %x:%x\n", u32PhysAddr, SegAhci, &AhciData->abFisRecv);
794
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FB, u32PhysAddr);
795
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_FBU, 0L);
796
 
 
797
 
    u32PhysAddr = ahci_addr_to_phys(SegAhci, &AhciData->abCmdHdr);
798
 
    VBOXAHCI_DEBUG("AHCI: CMD list area %lx\n", u32PhysAddr);
799
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLB, u32PhysAddr);
800
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_CLBU, 0L);
 
458
    //@todo: just one memset?
 
459
    _fmemset(&ahci->aCmdHdr[0], 0, sizeof(ahci->aCmdHdr));
 
460
    _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
 
461
    _fmemset(&ahci->abFisRecv[0], 0, sizeof(ahci->abFisRecv));
 
462
 
 
463
    DBG_AHCI("AHCI: FIS receive area %lx from %x:%x\n",
 
464
             ahci_addr_to_phys(&ahci->abFisRecv), FP_SEG(ahci->abFisRecv), FP_OFF(ahci->abFisRecv));
 
465
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_FB, ahci_addr_to_phys(&ahci->abFisRecv));
 
466
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_FBU, 0);
 
467
 
 
468
    DBG_AHCI("AHCI: CMD list area %lx\n", ahci_addr_to_phys(&ahci->aCmdHdr));
 
469
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_CLB, ahci_addr_to_phys(&ahci->aCmdHdr));
 
470
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_CLBU, 0);
801
471
 
802
472
    /* Disable all interrupts. */
803
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0L);
804
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IS, 0xffffffffL);
 
473
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_IE, 0);
 
474
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_IS, 0xffffffff);
805
475
    /* Clear all errors. */
806
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SERR, 0xffffffffL);
807
 
 
808
 
    write_byte(SegAhci, &AhciData->port, u8Port);
809
 
}
810
 
 
811
 
/**
812
 
 * Write data to the device.
813
 
 */
814
 
static void ahci_cmd_data_out(SegAhci, u16IoBase, u8Port, u8Cmd, u32Lba, u16Sectors, SegData, OffData)
815
 
    Bit16u SegAhci, u16IoBase;
816
 
    Bit8u  u8Port, u8Cmd;
817
 
    Bit32u u32Lba;
818
 
    Bit16u u16Sectors;
819
 
    Bit16u SegData, OffData;
820
 
{
821
 
    Bit8u u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
822
 
 
823
 
    u8SectCount = (Bit8u)(u16Sectors & 0xff);
824
 
    u8SectCountExp = (Bit8u)((u16Sectors >> 8) & 0xff);;
825
 
    u8Sect = (Bit8u)(u32Lba & 0xff);
826
 
    u8SectExp = (Bit8u)((u32Lba >> 24) & 0xff);
827
 
    u8CylLow = (Bit8u)((u32Lba >> 8) & 0xff);
828
 
    u8CylLowExp = 0;
829
 
    u8CylHigh = (Bit8u)((u32Lba >> 16) & 0xff);
830
 
    u8CylHighExp = 0;
831
 
    u8Device = (1 << 6); /* LBA access */
832
 
 
833
 
    ahci_port_init(SegAhci, u16IoBase, u8Port);
834
 
    ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
835
 
                  u8Sect,0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
836
 
                  u8SectCountExp, SegData, OffData, u16Sectors * 512, 1);
837
 
}
838
 
 
839
 
/**
840
 
 * Read data from the device.
841
 
 */
842
 
static void ahci_cmd_data_in(SegAhci, u16IoBase, u8Port, u8Cmd, u32Lba, u16Sectors, SegData, OffData)
843
 
    Bit16u SegAhci, u16IoBase;
844
 
    Bit8u  u8Port, u8Cmd;
845
 
    Bit32u u32Lba;
846
 
    Bit16u u16Sectors;
847
 
    Bit16u SegData, OffData;
848
 
{
849
 
    Bit8u u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
850
 
 
851
 
    u8SectCount = (Bit8u)(u16Sectors & 0xff);
852
 
    u8SectCountExp = (Bit8u)((u16Sectors >> 8) & 0xff);;
853
 
    u8Sect = (Bit8u)(u32Lba & 0xff);
854
 
    u8SectExp = (Bit8u)((u32Lba >> 24) & 0xff);
855
 
    u8CylLow = (Bit8u)((u32Lba >> 8) & 0xff);
856
 
    u8CylLowExp = 0;
857
 
    u8CylHigh = (Bit8u)((u32Lba >> 16) & 0xff);
858
 
    u8CylHighExp = 0;
859
 
 
860
 
    u8Device = (1 << 6); /* LBA access */
861
 
 
862
 
    ahci_port_init(SegAhci, u16IoBase, u8Port);
863
 
    ahci_cmd_data(SegAhci, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
864
 
                  u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
865
 
                  u8SectCountExp, SegData, OffData, u16Sectors * 512, 0);
866
 
}
867
 
 
868
 
static void ahci_port_detect_device(SegAhci, u16IoBase, u8Port)
869
 
    Bit16u SegAhci;
870
 
    Bit16u u16IoBase;
871
 
    Bit8u u8Port;
872
 
{
873
 
    Bit32u val;
874
 
 
875
 
    ahci_port_init(SegAhci, u16IoBase, u8Port);
 
476
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_SERR, 0xffffffff);
 
477
 
 
478
    ahci->cur_port = u8Port;
 
479
    ahci->cur_prd  = 0;
 
480
}
 
481
 
 
482
/**
 
483
 * Read sectors from an attached AHCI device.
 
484
 *
 
485
 * @returns status code.
 
486
 * @param   bios_dsk    Pointer to disk request packet (in the 
 
487
 *                      EBDA).
 
488
 */
 
489
int ahci_read_sectors(bio_dsk_t __far *bios_dsk)
 
490
{
 
491
    uint16_t        device_id;
 
492
 
 
493
    device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
 
494
    if (device_id > BX_MAX_AHCI_DEVICES)
 
495
        BX_PANIC("%s: device_id out of range %d\n", __func__, device_id);
 
496
 
 
497
    DBG_AHCI("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__,
 
498
             bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id,
 
499
             bios_dsk->ahcidev[device_id].port);
 
500
 
 
501
    high_bits_save(bios_dsk->ahci_seg :> 0);
 
502
    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
 
503
    ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
 
504
    DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
 
505
    bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
 
506
#ifdef DMA_WORKAROUND
 
507
    rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 512 / 2);
 
508
#endif
 
509
    high_bits_restore(bios_dsk->ahci_seg :> 0);
 
510
    return 0;   //@todo!!
 
511
}
 
512
 
 
513
/**
 
514
 * Write sectors to an attached AHCI device.
 
515
 *
 
516
 * @returns status code.
 
517
 * @param   bios_dsk    Pointer to disk request packet (in the 
 
518
 *                      EBDA).
 
519
 */
 
520
int ahci_write_sectors(bio_dsk_t __far *bios_dsk)
 
521
{
 
522
    uint16_t        device_id;
 
523
 
 
524
    device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
 
525
    if (device_id > BX_MAX_AHCI_DEVICES)
 
526
        BX_PANIC("%s: device_id out of range %d\n", __func__, device_id);
 
527
 
 
528
    DBG_AHCI("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__,
 
529
             bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id,
 
530
             bios_dsk->ahcidev[device_id].port);
 
531
 
 
532
    high_bits_save(bios_dsk->ahci_seg :> 0);
 
533
    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
 
534
    ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
 
535
    DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
 
536
    bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
 
537
    high_bits_restore(bios_dsk->ahci_seg :> 0);
 
538
    return 0;   //@todo!!
 
539
}
 
540
 
 
541
//@todo: move
 
542
#define ATA_DATA_NO      0x00
 
543
#define ATA_DATA_IN      0x01
 
544
#define ATA_DATA_OUT     0x02
 
545
 
 
546
uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 
 
547
                         uint16_t skip_b, uint32_t length, uint8_t inout, char __far *buffer)
 
548
{
 
549
    bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
 
550
    ahci_t __far    *ahci;
 
551
 
 
552
    /* Data out is currently not supported. */
 
553
    if (inout == ATA_DATA_OUT) {
 
554
        BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
 
555
        return 1;
 
556
    }
 
557
 
 
558
    /* The skip length must be even. */
 
559
    if (skip_b & 1) {
 
560
        DBG_AHCI("%s: skip must be even (%04x)\n", __func__, skip_b);
 
561
        return 1;
 
562
    }
 
563
 
 
564
    /* Convert to AHCI specific device number. */
 
565
    device_id = VBOX_GET_AHCI_DEVICE(device_id);
 
566
 
 
567
    DBG_AHCI("%s: reading %lu bytes, skip %u/%u, device %d, port %d\n", __func__,
 
568
             length, bios_dsk->drqp.skip_b, bios_dsk->drqp.skip_a, 
 
569
             device_id, bios_dsk->ahcidev[device_id].port);
 
570
    DBG_AHCI("%s: reading %u %u-byte sectors\n", __func__,
 
571
             bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz);
 
572
 
 
573
    bios_dsk->drqp.lba     = (uint32_t)length << 8;     //@todo: xfer length limit
 
574
    bios_dsk->drqp.buffer  = buffer;
 
575
    bios_dsk->drqp.nsect   = length / bios_dsk->drqp.sect_sz;
 
576
//    bios_dsk->drqp.sect_sz = 2048;
 
577
 
 
578
    ahci = bios_dsk->ahci_seg :> 0;
 
579
    high_bits_save(ahci);
 
580
 
 
581
    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
 
582
 
 
583
    /* Copy the ATAPI command where the HBA can fetch it. */
 
584
    _fmemcpy(ahci->abAcmd, cmdbuf, cmdlen);
 
585
 
 
586
    /* Reset transferred counts. */
 
587
    // @todo: clear in calling code?
 
588
    bios_dsk->drqp.trsfsectors = 0;
 
589
    bios_dsk->drqp.trsfbytes   = 0;
 
590
 
 
591
    /* Set up a PRD entry to throw away the beginning of the transfer. */
 
592
    if (bios_dsk->drqp.skip_b) {
 
593
        ahci->aPrdt[0].len       = bios_dsk->drqp.skip_b - 1;
 
594
        ahci->aPrdt[0].phys_addr = ahci->sink_buf_phys;
 
595
        ahci->cur_prd++;
 
596
    }
 
597
 
 
598
    ahci_cmd_data(bios_dsk, ATA_CMD_PACKET);
 
599
    DBG_AHCI("%s: transferred %lu bytes\n", __func__, ahci->aCmdHdr[1]);
 
600
    bios_dsk->drqp.trsfbytes = ahci->aCmdHdr[1];
 
601
#ifdef DMA_WORKAROUND
 
602
    rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.trsfbytes / 2);
 
603
#endif
 
604
    high_bits_restore(ahci);
 
605
 
 
606
    return ahci->aCmdHdr[1] == 0 ? 4 : 0;
 
607
//    return 0;   //@todo!!
 
608
}
 
609
 
 
610
static void ahci_port_detect_device(ahci_t __far *ahci, uint8_t u8Port)
 
611
{
 
612
    uint32_t            val;
 
613
    bio_dsk_t __far     *bios_dsk;
 
614
 
 
615
    ahci_port_init(ahci, u8Port);
 
616
 
 
617
    bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
876
618
 
877
619
    /* Reset connection. */
878
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SCTL, 0x01L);
 
620
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_SCTL, 0x01);
879
621
    /*
880
622
     * According to the spec we should wait at least 1msec until the reset
881
623
     * is cleared but this is a virtual controller so we don't have to.
882
624
     */
883
 
    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SCTL, 0x00L);
 
625
    VBOXAHCI_PORT_WRITE_REG(ahci->iobase, u8Port, AHCI_REG_PORT_SCTL, 0);
884
626
 
885
627
    /* Check if there is a device on the port. */
886
 
    VBOXAHCI_PORT_READ_REG(u16IoBase, u8Port, AHCI_REG_PORT_SSTS, val);
887
 
    if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3L)
 
628
    VBOXAHCI_PORT_READ_REG(ahci->iobase, u8Port, AHCI_REG_PORT_SSTS, val);
 
629
    if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3)
888
630
    {
889
 
        Bit8u idxDevice;
890
 
 
891
 
        idxDevice = read_byte(SegAhci, &AhciData->cDevices);
892
 
        VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port);
893
 
 
894
 
        if (idxDevice < AHCI_MAX_STORAGE_DEVICES)
 
631
        uint8_t     abBuffer[0x0200];
 
632
        uint8_t     hdcount, devcount_ahci, hd_index;
 
633
        uint8_t     cdcount;
 
634
        uint8_t     removable;
 
635
 
 
636
        devcount_ahci = bios_dsk->ahci_devcnt;
 
637
 
 
638
        DBG_AHCI("AHCI: Device detected on port %d\n", u8Port);
 
639
 
 
640
        //@todo: Merge common HD/CDROM detection code
 
641
        if (devcount_ahci < BX_MAX_AHCI_DEVICES)
895
642
        {
896
643
            /* Device detected, enable FIS receive. */
897
 
            ahci_ctrl_set_bits(u16IoBase, VBOXAHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
 
644
            ahci_ctrl_set_bits(ahci->iobase, AHCI_PORT_REG(u8Port, AHCI_REG_PORT_CMD),
898
645
                               AHCI_REG_PORT_CMD_FRE);
899
646
 
900
647
            /* Check signature to determine device type. */
901
 
            VBOXAHCI_PORT_READ_REG(u16IoBase, u8Port, AHCI_REG_PORT_SIG, val);
902
 
            if (val == 0x101L)
 
648
            VBOXAHCI_PORT_READ_REG(ahci->iobase, u8Port, AHCI_REG_PORT_SIG, val);
 
649
            if (val == 0x101)
903
650
            {
904
 
                Bit8u idxHdCurr;
905
 
                Bit32u cSectors;
906
 
                Bit8u  abBuffer[0x0200];
907
 
                Bit8u  fRemovable;
908
 
                Bit16u cCylinders, cHeads, cSectorsPerTrack;
909
 
                Bit8u  cHardDisksOld;
910
 
                Bit8u  idxCmosChsBase;
 
651
                uint32_t    sectors;
 
652
                uint16_t    cylinders, heads, spt;
 
653
                uint16_t    lcylinders, lheads, lspt;
 
654
                uint8_t     idxCmosChsBase;
911
655
 
912
 
                idxHdCurr = read_byte(SegAhci, &AhciData->cHardDisks);
913
 
                VBOXAHCI_DEBUG("AHCI: Detected hard disk\n");
 
656
                DBG_AHCI("AHCI: Detected hard disk\n");
914
657
 
915
658
                /* Identify device. */
916
 
                ahci_cmd_data(SegAhci, u16IoBase, ATA_CMD_IDENTIFY_DEVICE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, get_SS(), abBuffer, sizeof(abBuffer), 0);
917
 
 
918
 
                write_byte(SegAhci, &AhciData->aDevices[idxDevice].port, u8Port);
919
 
 
920
 
                fRemovable       = (read_byte(get_SS(),abBuffer+0) & 0x80) ? 1 : 0;
921
 
                cCylinders       = read_word(get_SS(),abBuffer+(1*2)); // word 1
922
 
                cHeads           = read_word(get_SS(),abBuffer+(3*2)); // word 3
923
 
                cSectorsPerTrack = read_word(get_SS(),abBuffer+(6*2)); // word 6
924
 
                cSectors         = read_dword(get_SS(),abBuffer+(60*2)); // word 60 and word 61
 
659
                bios_dsk->drqp.lba     = 0;
 
660
                bios_dsk->drqp.buffer  = &abBuffer;
 
661
                bios_dsk->drqp.nsect   = 1;
 
662
                bios_dsk->drqp.sect_sz = 512;
 
663
                ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_DEVICE);
 
664
 
 
665
                /* Calculate index into the generic device table. */
 
666
                hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
 
667
 
 
668
                removable = *(abBuffer+0) & 0x80 ? 1 : 0;
 
669
                cylinders = *(uint16_t *)(abBuffer+(1*2));  // word 1
 
670
                heads     = *(uint16_t *)(abBuffer+(3*2));  // word 3
 
671
                spt       = *(uint16_t *)(abBuffer+(6*2));  // word 6
 
672
                sectors   = *(uint32_t *)(abBuffer+(60*2)); // word 60 and word 61
925
673
 
926
674
                /** @todo update sectors to be a 64 bit number (also lba...). */
927
 
                if (cSectors == 268435455)
928
 
                    cSectors = read_dword(get_SS(),abBuffer+(100*2)); // words 100 to 103 (someday)
929
 
 
930
 
                VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors);
931
 
 
932
 
                write_byte(SegAhci, &AhciData->aDevices[idxDevice].device,ATA_DEVICE_HD);
933
 
                write_byte(SegAhci, &AhciData->aDevices[idxDevice].removable, fRemovable);
934
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].blksize, 512);
935
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads, cHeads);
936
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders, cCylinders);
937
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt, cSectorsPerTrack);
938
 
                write_dword(SegAhci, &AhciData->aDevices[idxDevice].cSectors, cSectors);
 
675
                if (sectors == 0x0FFFFFFF)  /* For disks bigger than ~128GB */
 
676
                    sectors = *(uint32_t *)(abBuffer+(100*2)); // words 100 to 103 (someday)
 
677
 
 
678
                DBG_AHCI("AHCI: %ld sectors\n", sectors);
 
679
 
 
680
                bios_dsk->ahcidev[devcount_ahci].port = u8Port;
 
681
                bios_dsk->devices[hd_index].type        = DSK_TYPE_AHCI;
 
682
                bios_dsk->devices[hd_index].device      = DSK_DEVICE_HD;
 
683
                bios_dsk->devices[hd_index].removable   = removable;
 
684
                bios_dsk->devices[hd_index].lock        = 0;
 
685
                bios_dsk->devices[hd_index].blksize     = 512;
 
686
                bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA;
 
687
                bios_dsk->devices[hd_index].sectors     = sectors;
 
688
 
 
689
                bios_dsk->devices[hd_index].pchs.heads     = heads;
 
690
                bios_dsk->devices[hd_index].pchs.cylinders = cylinders;
 
691
                bios_dsk->devices[hd_index].pchs.spt       = spt;
939
692
 
940
693
                /* Get logical CHS geometry. */
941
 
                switch (idxDevice)
 
694
                switch (devcount_ahci)
942
695
                {
943
696
                    case 0:
944
697
                        idxCmosChsBase = 0x40;
955
708
                    default:
956
709
                        idxCmosChsBase = 0;
957
710
                }
958
 
                if (idxCmosChsBase != 0)
 
711
                if (idxCmosChsBase && inb_cmos(idxCmosChsBase+7))
959
712
                {
960
 
                    cCylinders = inb_cmos(idxCmosChsBase) + (inb_cmos(idxCmosChsBase+1) << 8);
961
 
                    cHeads = inb_cmos(idxCmosChsBase+2);
962
 
                    cSectorsPerTrack = inb_cmos(idxCmosChsBase+7);
 
713
                    lcylinders = inb_cmos(idxCmosChsBase + 0) + (inb_cmos(idxCmosChsBase + 1) << 8);
 
714
                    lheads     = inb_cmos(idxCmosChsBase + 2);
 
715
                    lspt       = inb_cmos(idxCmosChsBase + 7);
963
716
                }
964
717
                else
965
718
                {
966
 
                    cCylinders = 0;
967
 
                    cHeads = 0;
968
 
                    cSectorsPerTrack = 0;
 
719
                    //@todo: What should we really do if logical geometry isn't in the CMOS?
 
720
                    lcylinders = cylinders;
 
721
                    lheads     = heads;
 
722
                    lspt       = spt;
969
723
                }
970
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads, cHeads);
971
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders, cCylinders);
972
 
                write_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt, cSectorsPerTrack);
973
 
 
974
 
                write_byte(SegAhci, &AhciData->aHdIdMap[idxHdCurr], idxDevice);
975
 
                idxHdCurr++;
976
 
                write_byte(SegAhci, &AhciData->cHardDisks, idxHdCurr);
 
724
                BX_INFO("AHCI %d-P#%d: PCHS=%u/%d/%d LCHS=%u/%u/%u %ld sectors\n", devcount_ahci,
 
725
                        u8Port, cylinders, heads, spt, lcylinders, lheads, lspt, sectors);
 
726
 
 
727
                bios_dsk->devices[hd_index].lchs.heads     = lheads;
 
728
                bios_dsk->devices[hd_index].lchs.cylinders = lcylinders;
 
729
                bios_dsk->devices[hd_index].lchs.spt       = lspt;
 
730
 
 
731
                /* Store the ID of the disk in the BIOS hdidmap. */
 
732
                hdcount = bios_dsk->hdcount;
 
733
                bios_dsk->hdidmap[hdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
 
734
                hdcount++;
 
735
                bios_dsk->hdcount = hdcount;
977
736
 
978
737
                /* Update hdcount in the BDA. */
979
 
                cHardDisksOld = read_byte(0x40, 0x75);
980
 
                cHardDisksOld++;
981
 
                write_byte(0x40, 0x75, cHardDisksOld);
 
738
                hdcount = read_byte(0x40, 0x75);
 
739
                hdcount++;
 
740
                write_byte(0x40, 0x75, hdcount);                
982
741
            }
983
742
            else if (val == 0xeb140101)
984
743
            {
985
 
                VBOXAHCI_DEBUG("AHCI: Detected ATAPI device\n");
 
744
                DBG_AHCI("AHCI: Detected ATAPI device\n");
 
745
 
 
746
                /* Identify packet device. */
 
747
                bios_dsk->drqp.lba     = 0;
 
748
                bios_dsk->drqp.buffer  = &abBuffer;
 
749
                bios_dsk->drqp.nsect   = 1;
 
750
                bios_dsk->drqp.sect_sz = 512;
 
751
                ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_PACKET);
 
752
 
 
753
                /* Calculate index into the generic device table. */
 
754
                hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
 
755
 
 
756
                removable = *(abBuffer+0) & 0x80 ? 1 : 0;
 
757
 
 
758
                bios_dsk->ahcidev[devcount_ahci].port = u8Port;
 
759
                bios_dsk->devices[hd_index].type      = DSK_TYPE_AHCI;
 
760
                bios_dsk->devices[hd_index].device    = DSK_DEVICE_CDROM;
 
761
                bios_dsk->devices[hd_index].removable = removable;
 
762
                bios_dsk->devices[hd_index].blksize   = 2048;
 
763
 
 
764
                /* Store the ID of the device in the BIOS cdidmap. */
 
765
                cdcount = bios_dsk->cdcount;
 
766
                bios_dsk->cdidmap[cdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
 
767
                cdcount++;
 
768
                bios_dsk->cdcount = cdcount;
986
769
            }
987
770
            else
988
 
                VBOXAHCI_DEBUG("AHCI: Unknown device ignoring\n");
 
771
                DBG_AHCI("AHCI: Ignoring unknown device\n");
989
772
 
990
 
            idxDevice++;
991
 
            write_byte(SegAhci, &AhciData->cDevices, idxDevice);
 
773
            devcount_ahci++;
 
774
            bios_dsk->ahci_devcnt = devcount_ahci;
992
775
        }
993
776
        else
994
 
            VBOXAHCI_DEBUG("AHCI: Reached maximum device count, skipping\n");
995
 
    }
996
 
}
997
 
 
998
 
#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
999
 
 
1000
 
/**
1001
 
 * Int 13 handler.
1002
 
 */
1003
 
static void ahci_int13(RET, ES, DS, DI, SI, BP, SP, BX, DX, CX, AX, IPIRET, CSIRET, FLAGSIRET, IP, CS, FLAGS)
1004
 
    Bit16u RET, ES, DS, AX, CX, DX, BX, SP, BP, SI, DI, IPIRET, CSIRET, FLAGSIRET, IP, CS, FLAGS;
1005
 
{
1006
 
    Bit16u ebda_seg;
1007
 
    Bit16u SegAhci, u16IoBase;
1008
 
    Bit8u  idxDevice;
1009
 
    Bit8u  cHardDisksOld;
1010
 
    Bit8u  u8Port;
1011
 
 
1012
 
    Bit32u lba;
1013
 
    Bit16u cylinder, head, sector;
1014
 
    Bit16u segment, offset;
1015
 
    Bit16u npc, nph, npspt, nlc, nlh, nlspt;
1016
 
    Bit16u size, count;
1017
 
    Bit8u  status;
1018
 
 
1019
 
    VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13 AX=%x CX=%x DX=%x BX=%x SP=%x BP=%x SI=%x DI=%x IP=%x CS=%x FLAGS=%x\n",
1020
 
                         AX, CX, DX, BX, SP, BP, SI, DI, IP, CS, FLAGS);
1021
 
 
1022
 
    ebda_seg  = read_word(0x0040, 0x000E);
1023
 
    SegAhci   = read_word(ebda_seg, &EbdaData->SegAhci);
1024
 
    u16IoBase = read_word(SegAhci, &AhciData->iobase);
1025
 
    VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13: SegAhci=%x u16IoBase=%x\n", SegAhci, u16IoBase);
1026
 
 
1027
 
    cHardDisksOld = read_byte(SegAhci, &AhciData->cHardDisksOld);
1028
 
 
1029
 
    /* Check if the device is controlled by us first. */
1030
 
    if (   (GET_DL() < 0x80)
1031
 
        || (GET_DL() < 0x80 + cHardDisksOld)
1032
 
        || ((GET_DL() & 0xe0) != 0x80) /* No CD-ROM drives supported for now */)
1033
 
    {
1034
 
        VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13 device not controlled by us, forwarding to old handler (%d)\n", cHardDisksOld);
1035
 
        /* Fill the iret frame to jump to the old handler. */
1036
 
        IPIRET    = read_word(SegAhci, &AhciData->pfnInt13Old);
1037
 
        CSIRET    = 0xf000;
1038
 
        FLAGSIRET = FLAGS;
1039
 
        RET       = 1;
1040
 
        return;
1041
 
    }
1042
 
 
1043
 
    idxDevice = read_byte(SegAhci, &AhciData->aHdIdMap[GET_DL()-0x80-cHardDisksOld]);
1044
 
 
1045
 
    if (idxDevice >= AHCI_MAX_STORAGE_DEVICES)
1046
 
    {
1047
 
        VBOXAHCI_INT13_DEBUG("AHCI: ahci_int13: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_DL());
1048
 
        goto ahci_int13_fail;
1049
 
    }
1050
 
 
1051
 
    u8Port = read_byte(SegAhci, &AhciData->aDevices[idxDevice].port);
1052
 
 
1053
 
    switch (GET_AH())
1054
 
    {
1055
 
        case 0x00: /* disk controller reset */
1056
 
        {
1057
 
            /** @todo: not really important I think. */
1058
 
            goto ahci_int13_success;
1059
 
            break;
1060
 
        }
1061
 
        case 0x01: /* read disk status */
1062
 
        {
1063
 
            status = read_byte(0x0040, 0x0074);
1064
 
            SET_AH(status);
1065
 
            SET_DISK_RET_STATUS(0);
1066
 
            /* set CF if error status read */
1067
 
            if (status)
1068
 
                goto ahci_int13_fail_nostatus;
1069
 
            else
1070
 
                goto ahci_int13_success_noah;
1071
 
            break;
1072
 
        }
1073
 
        case 0x02: // read disk sectors
1074
 
        case 0x03: // write disk sectors
1075
 
        case 0x04: // verify disk sectors
1076
 
        {
1077
 
            count       = GET_AL();
1078
 
            cylinder    = GET_CH();
1079
 
            cylinder   |= ( ((Bit16u) GET_CL()) << 2) & 0x300;
1080
 
            sector      = (GET_CL() & 0x3f);
1081
 
            head        = GET_DH();
1082
 
 
1083
 
            segment = ES;
1084
 
            offset  = BX;
1085
 
 
1086
 
            if ( (count > 128) || (count == 0) )
1087
 
            {
1088
 
                BX_INFO("int13_harddisk: function %02x, count out of range!\n",GET_AH());
1089
 
                goto ahci_int13_fail;
1090
 
            }
1091
 
 
1092
 
            nlc   = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders);
1093
 
            nlh   = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads);
1094
 
            nlspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt);
1095
 
 
1096
 
            // sanity check on cyl heads, sec
1097
 
            if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt ))
1098
 
            {
1099
 
              BX_INFO("ahci_int13: function %02x, disk %02x, parameters out of range %04x/%04x/%04x!\n", GET_AH(), GET_DL(), cylinder, head, sector);
1100
 
              goto ahci_int13_fail;
1101
 
            }
1102
 
 
1103
 
            // FIXME verify
1104
 
            if ( GET_AH() == 0x04 )
1105
 
                goto ahci_int13_success;
1106
 
 
1107
 
            lba = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1;
1108
 
 
1109
 
            status = 0;
1110
 
            if ( GET_AH() == 0x02 )
1111
 
                ahci_cmd_data_in(SegAhci, u16IoBase, u8Port, AHCI_CMD_READ_DMA_EXT, lba, count, segment, offset);
1112
 
            else
1113
 
                ahci_cmd_data_out(SegAhci, u16IoBase, u8Port, AHCI_CMD_WRITE_DMA_EXT, lba, count, segment, offset);
1114
 
 
1115
 
            // Set nb of sector transferred
1116
 
            SET_AL(read_word(ebda_seg, &EbdaData->ata.trsfsectors));
1117
 
 
1118
 
            if (status != 0)
1119
 
            {
1120
 
                BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
1121
 
                SET_AH(0x0c);
1122
 
                goto ahci_int13_fail_noah;
1123
 
            }
1124
 
 
1125
 
            goto ahci_int13_success;
1126
 
            break;
1127
 
        }
1128
 
        case 0x05: /* format disk track */
1129
 
            BX_INFO("format disk track called\n");
1130
 
            goto ahci_int13_success;
1131
 
            break;
1132
 
        case 0x08: /* read disk drive parameters */
1133
 
        {
1134
 
            // Get logical geometry from table
1135
 
            nlc   = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.cylinders);
1136
 
            nlh   = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.heads);
1137
 
            nlspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].lchs.spt);
1138
 
 
1139
 
            count = read_byte(SegAhci, &AhciData->cHardDisks); /** @todo correct? */
1140
 
            /* Maximum cylinder number is just one less than the number of cylinders. */
1141
 
            nlc = nlc - 1; /* 0 based , last sector not used */
1142
 
            SET_AL(0);
1143
 
            SET_CH(nlc & 0xff);
1144
 
            SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
1145
 
            SET_DH(nlh - 1);
1146
 
            SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
1147
 
            // FIXME should set ES & DI
1148
 
            goto ahci_int13_success;
1149
 
            break;
1150
 
        }
1151
 
        case 0x10: /* check drive ready */
1152
 
        {
1153
 
            /** @todo */
1154
 
            goto ahci_int13_success;
1155
 
            break;
1156
 
        }
1157
 
        case 0x15: /* read disk drive size */
1158
 
        {
1159
 
            // Get physical geometry from table
1160
 
            npc   = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders);
1161
 
            nph   = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads);
1162
 
            npspt = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt);
1163
 
 
1164
 
            // Compute sector count seen by int13
1165
 
            lba = (Bit32u)npc * (Bit32u)nph * (Bit32u)npspt;
1166
 
            CX = lba >> 16;
1167
 
            DX = lba & 0xffff;
1168
 
 
1169
 
            SET_AH(3);  // hard disk accessible
1170
 
            goto ahci_int13_success_noah;
1171
 
            break;
1172
 
        }
1173
 
#if 0
1174
 
        case 0x41: // IBM/MS installation check
1175
 
        {
1176
 
            BX=0xaa55;     // install check
1177
 
            SET_AH(0x30);  // EDD 3.0
1178
 
            CX=0x0007;     // ext disk access and edd, removable supported
1179
 
            goto ahci_int13_success_noah;
1180
 
            break;
1181
 
        }
1182
 
        case 0x42: // IBM/MS extended read
1183
 
        case 0x43: // IBM/MS extended write
1184
 
        case 0x44: // IBM/MS verify
1185
 
        case 0x47: // IBM/MS extended seek
1186
 
        {
1187
 
            count=read_word(DS, SI+(Bit16u)&Int13Ext->count);
1188
 
            segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment);
1189
 
            offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset);
1190
 
 
1191
 
            // Can't use 64 bits lba
1192
 
            lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2);
1193
 
            if (lba != 0L)
1194
 
            {
1195
 
                BX_PANIC("int13_harddisk: function %02x. Can't use 64bits lba\n",GET_AH());
1196
 
                goto ahci_int13_fail;
1197
 
            }
1198
 
 
1199
 
            // Get 32 bits lba and check
1200
 
            lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1);
1201
 
 
1202
 
            if (lba >= read_word(SegAhci, &AhciData->aDevices[idxDevice].cSectors) )
1203
 
            {
1204
 
                BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH());
1205
 
                goto ahci_int13_fail;
1206
 
            }
1207
 
 
1208
 
            // If verify or seek
1209
 
            if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
1210
 
                goto ahci_int13_success;
1211
 
 
1212
 
            // Execute the command
1213
 
            if ( GET_AH() == 0x42 )
1214
 
            {
1215
 
                if (lba + count >= 268435456)
1216
 
                    status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS_EXT, count, 0, 0, 0, lba, segment, offset);
1217
 
                else
1218
 
                {
1219
 
                    write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,count * 0x200);
1220
 
                    status=ata_cmd_data_in(device, ATA_CMD_READ_MULTIPLE, count, 0, 0, 0, lba, segment, offset);
1221
 
                    write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0x200);
1222
 
                }
1223
 
            }
1224
 
            else
1225
 
            {
1226
 
                if (lba + count >= 268435456)
1227
 
                    status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS_EXT, count, 0, 0, 0, lba, segment, offset);
1228
 
                else
1229
 
                    status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba, segment, offset);
1230
 
            }
1231
 
 
1232
 
            count=read_word(ebda_seg, &EbdaData->ata.trsfsectors);
1233
 
            write_word(DS, SI+(Bit16u)&Int13Ext->count, count);
1234
 
 
1235
 
            if (status != 0)
1236
 
            {
1237
 
                BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status);
1238
 
                SET_AH(0x0c);
1239
 
                goto ahci_int13_fail_noah;
1240
 
            }
1241
 
            goto ahci_int13_success;
1242
 
            break;
1243
 
        }
1244
 
        case 0x45: // IBM/MS lock/unlock drive
1245
 
        case 0x49: // IBM/MS extended media change
1246
 
            goto ahci_int13_success;    // Always success for HD
1247
 
            break;
1248
 
        case 0x46: // IBM/MS eject media
1249
 
            SET_AH(0xb2);          // Volume Not Removable
1250
 
            goto ahci_int13_fail_noah;  // Always fail for HD
1251
 
            break;
1252
 
 
1253
 
        case 0x48: // IBM/MS get drive parameters
1254
 
            size=read_word(DS,SI+(Bit16u)&Int13DPT->size);
1255
 
 
1256
 
            // Buffer is too small
1257
 
            if(size < 0x1a)
1258
 
                goto ahci_int13_fail;
1259
 
 
1260
 
            // EDD 1.x
1261
 
            if(size >= 0x1a)
1262
 
            {
1263
 
                Bit16u   blksize;
1264
 
 
1265
 
                npc     = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.cylinders);
1266
 
                nph     = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.heads);
1267
 
                npspt   = read_word(SegAhci, &AhciData->aDevices[idxDevice].pchs.spt);
1268
 
                lba     = read_dword(SegAhci, &AhciData->aDevices[idxDevice].cSectors);
1269
 
                blksize = read_word(SegAhci, &AhciData->aDevices[idxDevice].blksize);
1270
 
 
1271
 
                write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
1272
 
                write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
1273
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
1274
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph);
1275
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt);
1276
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba);  // FIXME should be Bit64
1277
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, 0L);
1278
 
                write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize);
1279
 
            }
1280
 
 
1281
 
#if 0 /* Disable EDD 2.X and 3.x for now, don't know if it is required by any OS loader yet */
1282
 
            // EDD 2.x
1283
 
            if(size >= 0x1e)
1284
 
            {
1285
 
                Bit8u  channel, dev, irq, mode, checksum, i, translation;
1286
 
                Bit16u iobase1, iobase2, options;
1287
 
 
1288
 
                translation = ATA_TRANSLATION_LBA;
1289
 
 
1290
 
                write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1e);
1291
 
 
1292
 
                write_word(DS, SI+(Bit16u)&Int13DPT->dpte_segment, ebda_seg);
1293
 
                write_word(DS, SI+(Bit16u)&Int13DPT->dpte_offset, &EbdaData->ata.dpte);
1294
 
 
1295
 
                // Fill in dpte
1296
 
                channel = device / 2;
1297
 
                iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
1298
 
                iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2);
1299
 
                irq = read_byte(ebda_seg, &EbdaData->ata.channels[channel].irq);
1300
 
                mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
1301
 
                translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation);
1302
 
 
1303
 
                options  = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation
1304
 
                options |= (1<<4); // lba translation
1305
 
                options |= (mode==ATA_MODE_PIO32?1:0<<7);
1306
 
                options |= (translation==ATA_TRANSLATION_LBA?1:0<<9);
1307
 
                options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9);
1308
 
 
1309
 
                write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
1310
 
                write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
1311
 
                //write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | /*(device % 2))<<4*/ );
1312
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
1313
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
1314
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.blkcount, 1 );
1315
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.dma, 0 );
1316
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
1317
 
                write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
1318
 
                write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
1319
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
1320
 
 
1321
 
                checksum=0;
1322
 
                for (i=0; i<15; i++)
1323
 
                    checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
1324
 
 
1325
 
                checksum = -checksum;
1326
 
                write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
1327
 
            }
1328
 
 
1329
 
            // EDD 3.x
1330
 
            if(size >= 0x42)
1331
 
            {
1332
 
                Bit8u channel, iface, checksum, i;
1333
 
                Bit16u iobase1;
1334
 
 
1335
 
                channel = device / 2;
1336
 
                iface = read_byte(ebda_seg, &EbdaData->ata.channels[channel].iface);
1337
 
                iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1);
1338
 
 
1339
 
                write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x42);
1340
 
                write_word(DS, SI+(Bit16u)&Int13DPT->key, 0xbedd);
1341
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->dpi_length, 0x24);
1342
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->reserved1, 0);
1343
 
                write_word(DS, SI+(Bit16u)&Int13DPT->reserved2, 0);
1344
 
 
1345
 
                if (iface==ATA_IFACE_ISA) {
1346
 
                  write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[0], 'I');
1347
 
                  write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[1], 'S');
1348
 
                  write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[2], 'A');
1349
 
                  write_byte(DS, SI+(Bit16u)&Int13DPT->host_bus[3], 0);
1350
 
                  }
1351
 
                else {
1352
 
                  // FIXME PCI
1353
 
                  }
1354
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[0], 'A');
1355
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[1], 'T');
1356
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[2], 'A');
1357
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->iface_type[3], 0);
1358
 
 
1359
 
                if (iface==ATA_IFACE_ISA) {
1360
 
                  write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[0], iobase1);
1361
 
                  write_word(DS, SI+(Bit16u)&Int13DPT->iface_path[2], 0);
1362
 
                  write_dword(DS, SI+(Bit16u)&Int13DPT->iface_path[4], 0L);
1363
 
                  }
1364
 
                else {
1365
 
                  // FIXME PCI
1366
 
                  }
1367
 
                //write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[0], device%2);
1368
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->device_path[1], 0);
1369
 
                write_word(DS, SI+(Bit16u)&Int13DPT->device_path[2], 0);
1370
 
                write_dword(DS, SI+(Bit16u)&Int13DPT->device_path[4], 0L);
1371
 
 
1372
 
                checksum=0;
1373
 
                for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
1374
 
                checksum = -checksum;
1375
 
                write_byte(DS, SI+(Bit16u)&Int13DPT->checksum, checksum);
1376
 
            }
1377
 
#endif
1378
 
            goto ahci_int13_success;
1379
 
            break;
1380
 
        case 0x4e: // // IBM/MS set hardware configuration
1381
 
            // DMA, prefetch, PIO maximum not supported
1382
 
            switch (GET_AL())
1383
 
            {
1384
 
                case 0x01:
1385
 
                case 0x03:
1386
 
                case 0x04:
1387
 
                case 0x06:
1388
 
                    goto ahci_int13_success;
1389
 
                    break;
1390
 
                default :
1391
 
                    goto ahci_int13_fail;
1392
 
            }
1393
 
            break;
1394
 
#endif
1395
 
        case 0x09: /* initialize drive parameters */
1396
 
        case 0x0c: /* seek to specified cylinder */
1397
 
        case 0x0d: /* alternate disk reset */
1398
 
        case 0x11: /* recalibrate */
1399
 
        case 0x14: /* controller internal diagnostic */
1400
 
            BX_INFO("ahci_int13: function %02xh unimplemented, returns success\n", GET_AH());
1401
 
            goto ahci_int13_success;
1402
 
            break;
1403
 
 
1404
 
        case 0x0a: /* read disk sectors with ECC */
1405
 
        case 0x0b: /* write disk sectors with ECC */
1406
 
        case 0x18: // set media type for format
1407
 
        case 0x50: // IBM/MS send packet command
1408
 
        default:
1409
 
            BX_INFO("ahci_int13: function %02xh unsupported, returns fail\n", GET_AH());
1410
 
            goto ahci_int13_fail;
1411
 
            break;
1412
 
    }
1413
 
 
1414
 
ahci_int13_fail:
1415
 
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
1416
 
ahci_int13_fail_noah:
1417
 
    SET_DISK_RET_STATUS(GET_AH());
1418
 
ahci_int13_fail_nostatus:
1419
 
    SET_CF();     // error occurred
1420
 
    return;
1421
 
 
1422
 
ahci_int13_success:
1423
 
    SET_AH(0x00); // no error
1424
 
ahci_int13_success_noah:
1425
 
    SET_DISK_RET_STATUS(0x00);
1426
 
    CLEAR_CF();   // no error
1427
 
    return;
1428
 
}
1429
 
 
1430
 
#undef SET_DISK_RET_STATUS
1431
 
 
1432
 
/**
1433
 
 * Assembler part of the int 13 handler.
1434
 
 */
1435
 
ASM_START
1436
 
ahci_int13_handler:
1437
 
    ; Allocate space for an iret frame we have to use
1438
 
    ; to call the old int 13 handler
1439
 
    push #0x0000
1440
 
    push #0x0000
1441
 
    push #0x0000
1442
 
 
1443
 
    pusha                 ; Save 16bit values as arguments
1444
 
    push ds
1445
 
    push es
1446
 
    mov ax, #0            ; Allocate room for the return value on the stack
1447
 
    push ax
1448
 
    call _ahci_int13
1449
 
    pop ax
1450
 
    pop es
1451
 
    pop ds
1452
 
    cmp ax, #0x0          ; Check if the handler processed the request
1453
 
    je ahci_int13_out
1454
 
    popa                  ; Restore the caller environment
1455
 
    iret                  ; Call the old interrupt handler. Will not come back here.
1456
 
 
1457
 
ahci_int13_out:
1458
 
    popa
1459
 
    add sp, #6            ; Destroy the iret frame
1460
 
    iret
1461
 
ASM_END
1462
 
 
1463
 
/**
1464
 
 * Install the in13 interrupt handler
1465
 
 * preserving the previous one.
1466
 
 */
1467
 
static void ahci_install_int_handler(SegAhci)
1468
 
    Bit16u SegAhci;
1469
 
{
1470
 
 
1471
 
    Bit16u pfnInt13Old;
1472
 
 
1473
 
    VBOXAHCI_DEBUG("AHCI: Hooking int 13h vector\n");
1474
 
 
1475
 
    /* Read the old interrupt handler. */
1476
 
    pfnInt13Old = read_word(0x0000, 0x0013*4);
1477
 
    write_word(SegAhci, &AhciData->pfnInt13Old, pfnInt13Old);
1478
 
 
1479
 
    /* Set our own */
1480
 
    ASM_START
1481
 
 
1482
 
    push bp
1483
 
    mov bp, sp
1484
 
 
1485
 
    push ax
1486
 
    SET_INT_VECTOR(0x13, #0xF000, #ahci_int13_handler)
1487
 
    pop ax
1488
 
 
1489
 
    pop bp
1490
 
    ASM_END
1491
 
}
1492
 
 
1493
 
/**
1494
 
 * Allocates 1K from the base memory.
1495
 
 */
1496
 
static Bit16u ahci_mem_alloc()
1497
 
{
1498
 
    Bit16u cBaseMem1K;
1499
 
    Bit16u SegStart;
1500
 
 
1501
 
    cBaseMem1K = read_byte(0x00, 0x0413);
1502
 
 
1503
 
    VBOXAHCI_DEBUG("AHCI: %x K of base memory available\n", cBaseMem1K);
1504
 
 
1505
 
    if (cBaseMem1K == 0)
 
777
            DBG_AHCI("AHCI: Reached maximum device count, skipping\n");
 
778
    }
 
779
}
 
780
 
 
781
/**
 
782
 * Allocates 1K of conventional memory.
 
783
 */
 
784
static uint16_t ahci_mem_alloc(void)
 
785
{
 
786
    uint16_t    base_mem_kb;
 
787
    uint16_t    ahci_seg;
 
788
 
 
789
    base_mem_kb = read_word(0x00, 0x0413);
 
790
 
 
791
    DBG_AHCI("AHCI: %dK of base mem\n", base_mem_kb);
 
792
 
 
793
    if (base_mem_kb == 0)
1506
794
        return 0;
1507
795
 
1508
 
    cBaseMem1K--; /* Allocate one block. */
1509
 
    SegStart = (Bit16u)(((Bit32u)cBaseMem1K * 1024) >> 4); /* Calculate start segment. */
1510
 
 
1511
 
    write_byte(0x00, 0x0413, cBaseMem1K);
1512
 
 
1513
 
    return SegStart;
 
796
    base_mem_kb--; /* Allocate one block. */
 
797
    ahci_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */
 
798
 
 
799
    write_word(0x00, 0x0413, base_mem_kb);
 
800
 
 
801
    return ahci_seg;
1514
802
}
1515
803
 
1516
804
/**
1517
 
 * Initializes the SATA controller and detects attached devices.
 
805
 * Initializes the AHCI HBA and detects attached devices.
1518
806
 */
1519
 
static int ahci_ctrl_init(u16IoBase)
1520
 
    Bit16u u16IoBase;
 
807
static int ahci_hba_init(uint16_t io_base)
1521
808
{
1522
 
    Bit8u i, cPorts;
1523
 
    Bit32u val;
1524
 
    Bit16u ebda_seg;
1525
 
    Bit16u SegAhci;
 
809
    uint8_t             i, cPorts;
 
810
    uint32_t            val;
 
811
    uint16_t            ebda_seg;
 
812
    uint16_t            ahci_seg;
 
813
    bio_dsk_t __far     *bios_dsk;
 
814
    ahci_t __far        *ahci;
 
815
    
1526
816
 
1527
817
    ebda_seg = read_word(0x0040, 0x000E);
 
818
    bios_dsk = ebda_seg :> &EbdaData->bdisk;
1528
819
 
1529
 
    VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_VS, val);
1530
 
    VBOXAHCI_DEBUG("AHCI: Controller has version: 0x%x (major) 0x%x (minor)\n",
1531
 
                   ahci_ctrl_extract_bits(val, 0xffff0000, 16),
1532
 
                   ahci_ctrl_extract_bits(val, 0x0000ffff,  0));
 
820
    AHCI_READ_REG(io_base, AHCI_REG_VS, val);
 
821
    DBG_AHCI("AHCI: Controller version: 0x%x (major) 0x%x (minor)\n",
 
822
             ahci_ctrl_extract_bits(val, 0xffff0000, 16),
 
823
             ahci_ctrl_extract_bits(val, 0x0000ffff,  0));
1533
824
 
1534
825
    /* Allocate 1K of base memory. */
1535
 
    SegAhci = ahci_mem_alloc();
1536
 
    if (SegAhci == 0)
 
826
    ahci_seg = ahci_mem_alloc();
 
827
    if (ahci_seg == 0)
1537
828
    {
1538
 
        VBOXAHCI_DEBUG("AHCI: Could not allocate 1K of memory, can't boot from controller\n");
 
829
        DBG_AHCI("AHCI: Could not allocate 1K of memory, can't boot from controller\n");
1539
830
        return 0;
1540
831
    }
1541
 
 
1542
 
    write_word(ebda_seg, &EbdaData->SegAhci, SegAhci);
1543
 
    write_byte(SegAhci, &AhciData->port, 0xff);
1544
 
    write_word(SegAhci, &AhciData->iobase, u16IoBase);
1545
 
    write_byte(SegAhci, &AhciData->cHardDisksOld, read_byte(0x40, 0x75));
 
832
    DBG_AHCI("AHCI: ahci_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n", 
 
833
             ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_seg, sizeof(ebda_data_t));
 
834
 
 
835
    bios_dsk->ahci_seg    = ahci_seg;
 
836
    bios_dsk->ahci_devcnt = 0;
 
837
 
 
838
    ahci = ahci_seg :> 0;
 
839
    ahci->cur_port = 0xff;
 
840
    ahci->iobase   = io_base;
 
841
 
 
842
    /* Physical address of memory used for throwing away ATAPI data when reading 512-byte
 
843
     * blocks from 2048-byte CD sectors.
 
844
     */
 
845
    ahci->sink_buf_phys = 0xCC000;  //@todo: find some better place!
1546
846
 
1547
847
    /* Reset the controller. */
1548
 
    ahci_ctrl_set_bits(u16IoBase, AHCI_REG_GHC, AHCI_GHC_HR);
 
848
    ahci_ctrl_set_bits(io_base, AHCI_REG_GHC, AHCI_GHC_HR);
1549
849
    do
1550
850
    {
1551
 
        VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_GHC, val);
 
851
        AHCI_READ_REG(io_base, AHCI_REG_GHC, val);
1552
852
    } while (val & AHCI_GHC_HR != 0);
1553
853
 
1554
 
    VBOXAHCI_READ_REG(u16IoBase, AHCI_REG_CAP, val);
 
854
    AHCI_READ_REG(io_base, AHCI_REG_CAP, val);
1555
855
    cPorts = ahci_ctrl_extract_bits(val, 0x1f, 0) + 1; /* Extract number of ports.*/
1556
856
 
1557
 
    VBOXAHCI_DEBUG("AHCI: Controller has %u ports\n", cPorts);
 
857
    DBG_AHCI("AHCI: HBA has %u ports\n", cPorts);
1558
858
 
1559
859
    /* Go through the ports. */
1560
860
    i = 0;
1561
861
    while (i < 32)
1562
862
    {
1563
 
        if (ahci_ctrl_is_bit_set(u16IoBase, AHCI_REG_PI, RT_BIT_32(i)) != 0)
 
863
        if (ahci_ctrl_is_bit_set(io_base, AHCI_REG_PI, RT_BIT_32(i)) != 0)
1564
864
        {
1565
 
            VBOXAHCI_DEBUG("AHCI: Port %u is present\n", i);
1566
 
            ahci_port_detect_device(SegAhci, u16IoBase, i);
 
865
            DBG_AHCI("AHCI: Port %u is present\n", i);
 
866
            ahci_port_detect_device(ahci_seg :> 0, i);
1567
867
            cPorts--;
1568
868
            if (cPorts == 0)
1569
869
                break;
1571
871
        i++;
1572
872
    }
1573
873
 
1574
 
    if (read_byte(SegAhci, &AhciData->cDevices) > 0)
1575
 
    {
1576
 
        /*
1577
 
         * Init completed and there is at least one device present.
1578
 
         * Install our int13 handler.
1579
 
         */
1580
 
        ahci_install_int_handler(SegAhci);
1581
 
    }
1582
 
 
1583
874
    return 0;
1584
875
}
1585
876
 
1586
877
/**
1587
878
 * Init the AHCI driver and detect attached disks.
1588
879
 */
1589
 
void ahci_init( )
 
880
void BIOSCALL ahci_init(void)
1590
881
{
1591
 
    Bit16u ebda_seg;
1592
 
    Bit16u busdevfn;
1593
 
 
1594
 
    ebda_seg = read_word(0x0040, 0x000E);
1595
 
 
1596
 
    busdevfn = ahci_pci_find_classcode(0x00010601);
 
882
    uint16_t    busdevfn;
 
883
 
 
884
    busdevfn = pci_find_classcode(0x00010601);
1597
885
    if (busdevfn != VBOX_AHCI_NO_DEVICE)
1598
886
    {
1599
 
        Bit8u u8Bus, u8DevFn;
1600
 
        Bit8u u8PciCapOff;
 
887
        uint8_t     u8Bus, u8DevFn;
 
888
        uint8_t     u8PciCapOff;
1601
889
 
1602
890
        u8Bus = (busdevfn & 0xff00) >> 8;
1603
891
        u8DevFn = busdevfn & 0x00ff;
1604
892
 
1605
 
        VBOXAHCI_DEBUG("Found AHCI controller at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
 
893
        DBG_AHCI("AHCI HBA at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
1606
894
 
1607
895
        /* Examine the capability list and search for the Serial ATA Capability Register. */
1608
 
        u8PciCapOff = ahci_pci_read_config_byte(u8Bus, u8DevFn, PCI_CONFIG_CAP);
 
896
        u8PciCapOff = pci_read_config_byte(u8Bus, u8DevFn, PCI_CONFIG_CAP);
1609
897
 
1610
898
        while (u8PciCapOff != 0)
1611
899
        {
1612
 
            Bit8u u8PciCapId = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
 
900
            uint8_t     u8PciCapId = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
1613
901
 
1614
 
            VBOXAHCI_DEBUG("Capability ID 0x%x at offset 0x%x found\n", u8PciCapId, u8PciCapOff);
 
902
            DBG_AHCI("Capability ID 0x%x at 0x%x\n", u8PciCapId, u8PciCapOff);
1615
903
 
1616
904
            if (u8PciCapId == PCI_CAP_ID_SATACR)
1617
905
                break;
1618
906
 
1619
907
            /* Go on to the next capability. */
1620
 
            u8PciCapOff = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 1);
 
908
            u8PciCapOff = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff + 1);
1621
909
        }
1622
910
 
1623
911
        if (u8PciCapOff != 0)
1624
912
        {
1625
 
            Bit8u u8Rev;
 
913
            uint8_t     u8Rev;
1626
914
 
1627
 
            VBOXAHCI_DEBUG("AHCI controller with SATA Capability register at offset 0x%x found\n", u8PciCapOff);
 
915
            DBG_AHCI("AHCI HBA with SATA Capability register at 0x%x\n", u8PciCapOff);
1628
916
 
1629
917
            /* Advance to the stuff behind the id and next capability pointer. */
1630
918
            u8PciCapOff += 2;
1631
919
 
1632
 
            u8Rev = ahci_pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
 
920
            u8Rev = pci_read_config_byte(u8Bus, u8DevFn, u8PciCapOff);
1633
921
            if (u8Rev == 0x10)
1634
922
            {
1635
923
                /* Read the SATACR1 register and get the bar and offset of the index/data pair register. */
1636
 
                Bit8u  u8Bar = 0x00;
1637
 
                Bit16u u16Off = 0x00;
1638
 
                Bit16u u16BarOff = ahci_pci_read_config_word(u8Bus, u8DevFn, u8PciCapOff + 2);
 
924
                uint8_t     u8Bar = 0x00;
 
925
                uint16_t    u16Off = 0x00;
 
926
                uint16_t    u16BarOff = pci_read_config_word(u8Bus, u8DevFn, u8PciCapOff + 2);
1639
927
 
1640
 
                VBOXAHCI_DEBUG("SATACR1 register contains 0x%x\n", u16BarOff);
 
928
                DBG_AHCI("SATACR1: 0x%x\n", u16BarOff);
1641
929
 
1642
930
                switch (u16BarOff & 0xf)
1643
931
                {
1662
950
                    case 0x0f:
1663
951
                    default:
1664
952
                        /* Reserved or unsupported. */
1665
 
                        VBOXAHCI_DEBUG("BAR location 0x%x is unsupported\n", u16BarOff & 0xf);
 
953
                        DBG_AHCI("BAR 0x%x unsupported\n", u16BarOff & 0xf);
1666
954
                }
1667
955
 
1668
956
                /* Get the offset inside the BAR from bits 4:15. */
1670
958
 
1671
959
                if (u8Bar != 0x00)
1672
960
                {
1673
 
                    Bit32u u32Bar = ahci_pci_read_config_dword(u8Bus, u8DevFn, u8Bar);
 
961
                    uint32_t    u32Bar = pci_read_config_dword(u8Bus, u8DevFn, u8Bar);
1674
962
 
1675
 
                    VBOXAHCI_DEBUG("BAR at offset 0x%x contains 0x%x\n", u8Bar, u32Bar);
 
963
                    DBG_AHCI("BAR at 0x%x : 0x%x\n", u8Bar, u32Bar);
1676
964
 
1677
965
                    if ((u32Bar & 0x01) != 0)
1678
966
                    {
1679
 
                        int rc;
1680
 
                        Bit16u u16AhciIoBase = (u32Bar & 0xfff0) + u16Off;
 
967
                        int         rc;
 
968
                        uint16_t    u16AhciIoBase = (u32Bar & 0xfff0) + u16Off;
1681
969
 
1682
 
                        VBOXAHCI_DEBUG("I/O base is 0x%x\n", u16AhciIoBase);
1683
 
                        rc = ahci_ctrl_init(u16AhciIoBase);
 
970
                        DBG_AHCI("I/O base: 0x%x\n", u16AhciIoBase);
 
971
                        rc = ahci_hba_init(u16AhciIoBase);
1684
972
                    }
1685
973
                    else
1686
 
                        VBOXAHCI_DEBUG("BAR is MMIO\n");
 
974
                        DBG_AHCI("BAR is MMIO\n");
1687
975
                }
1688
976
            }
1689
977
            else
1690
 
                VBOXAHCI_DEBUG("Invalid revision 0x%x\n", u8Rev);
 
978
                DBG_AHCI("Invalid revision 0x%x\n", u8Rev);
1691
979
        }
1692
980
        else
1693
 
            VBOXAHCI_DEBUG("AHCI controller without usable Index/Data register pair found\n");
 
981
            DBG_AHCI("AHCI HBA with no usable Index/Data register pair!\n");
1694
982
    }
1695
983
    else
1696
 
        VBOXAHCI_DEBUG("No AHCI controller found\n");
 
984
        DBG_AHCI("No AHCI HBA!\n");
1697
985
}
1698