ide
This commit is contained in:
parent
977951fd95
commit
a1bf1cd7b4
@ -110,10 +110,8 @@ void Machine_Init()
|
|||||||
|
|
||||||
// XXX: disable interrupts here to avoid the timer interrupt firing before KTimer is initialized
|
// XXX: disable interrupts here to avoid the timer interrupt firing before KTimer is initialized
|
||||||
// alternatively, break the dependency or use an "initialized" flag in KTimer_Process
|
// alternatively, break the dependency or use an "initialized" flag in KTimer_Process
|
||||||
disable_interrupts();
|
|
||||||
PTimer_Init();
|
PTimer_Init();
|
||||||
KTimer_Init();
|
KTimer_Init();
|
||||||
enable_interrupts();
|
|
||||||
|
|
||||||
Thread_Init();
|
Thread_Init();
|
||||||
|
|
||||||
@ -132,19 +130,20 @@ void Machine_Init()
|
|||||||
PCI_Init(); // PCI BUS
|
PCI_Init(); // PCI BUS
|
||||||
BufCache_Init();
|
BufCache_Init();
|
||||||
|
|
||||||
while(1){
|
|
||||||
hlt();
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Open the primary disk and mount the root file system
|
* Open the primary disk and mount the root file system
|
||||||
*/
|
*/
|
||||||
Disk *root = Disk_GetByID(0, 0);
|
Disk *root = Disk_GetByID(0, 0);
|
||||||
if (!root)
|
if (!root)
|
||||||
Panic("No boot disk!");
|
Panic("No boot disk!");
|
||||||
VFS_MountRoot(root);
|
VFS_MountRoot(root);
|
||||||
|
|
||||||
Critical_Exit();
|
Critical_Exit();
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the idle thread
|
* Create the idle thread
|
||||||
*/
|
*/
|
||||||
|
256
sys/dev/ata.h
256
sys/dev/ata.h
@ -5,31 +5,243 @@
|
|||||||
#ifndef __ATA_H__
|
#ifndef __ATA_H__
|
||||||
#define __ATA_H__
|
#define __ATA_H__
|
||||||
|
|
||||||
typedef struct ATAIdentifyDevice
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LITTLE_ENDIAN
|
||||||
|
/*
|
||||||
|
* Drive parameter structure for ATA/ATAPI.
|
||||||
|
* Bit fields: WDC_* : common to ATA/ATAPI
|
||||||
|
* ATA_* : ATA only
|
||||||
|
* ATAPI_* : ATAPI only.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t _rsvd0[10]; // 0-9
|
/* drive info */
|
||||||
uint8_t serial[20]; // 10-19 - Serial
|
uint16_t atap_config; /* 0: general configuration */
|
||||||
uint16_t _rsvd1[3]; // 20-22
|
#define WDC_CFG_ATAPI_MASK 0xc000
|
||||||
uint8_t firmware[8]; // 23-26 - Firmware
|
#define WDC_CFG_ATAPI 0x8000
|
||||||
uint8_t model[40]; // 27-46 - Model
|
#define ATA_CFG_REMOVABLE 0x0080
|
||||||
uint16_t _rsvd2[16]; // 47-62 X
|
#define ATA_CFG_FIXED 0x0040
|
||||||
uint16_t dmaMode; // 63 - DMA Mode
|
#define ATAPI_CFG_TYPE_MASK 0x1f00
|
||||||
uint16_t _rsvd3[11]; // 64-74 X
|
#define ATAPI_CFG_TYPE(x) (((x) & ATAPI_CFG_TYPE_MASK) >> 8)
|
||||||
uint16_t queueDepth; // 75 - Queue Depth
|
#define ATAPI_CFG_TYPE_DIRECT 0x00
|
||||||
uint16_t sataCap; // 76 - SATA Capabilities
|
#define ATAPI_CFG_TYPE_SEQUENTIAL 0x01
|
||||||
uint16_t ncqCap; // 77 - NCQ Capabilities
|
#define ATAPI_CFG_TYPE_CDROM 0x05
|
||||||
uint16_t _rsvd4[8]; // 78-85
|
#define ATAPI_CFG_TYPE_OPTICAL 0x07
|
||||||
uint16_t deviceFlags; // 86 - Device Flags (48-bit Addressing)
|
#define ATAPI_CFG_TYPE_NODEVICE 0x1F
|
||||||
uint16_t deviceFlags2; // 87 - Device Flags 2 (SMART)
|
#define ATAPI_CFG_REMOV 0x0080
|
||||||
uint16_t udmaMode; // 88 - Ultra DMA Mode
|
#define ATAPI_CFG_DRQ_MASK 0x0060
|
||||||
uint16_t _rsvd5[11]; // 89-99
|
#define ATAPI_CFG_STD_DRQ 0x0000
|
||||||
uint64_t lbaSectors; // 100-103 - User Addressable Logical Sectors
|
#define ATAPI_CFG_IRQ_DRQ 0x0020
|
||||||
uint16_t _rsvd6[2]; // 104-105
|
#define ATAPI_CFG_ACCEL_DRQ 0x0040
|
||||||
uint16_t sectorSize; // 106 - Physical Sector Size
|
#define ATAPI_CFG_CMD_MASK 0x0003
|
||||||
uint16_t _rsvd7[148]; // 107-254
|
#define ATAPI_CFG_CMD_12 0x0000
|
||||||
uint16_t chksum; // 255 - Checksum
|
#define ATAPI_CFG_CMD_16 0x0001
|
||||||
|
/* words 1-9 are ATA only */
|
||||||
|
uint16_t atap_cylinders; /* 1: # of non-removable cylinders */
|
||||||
|
uint16_t __reserved1;
|
||||||
|
uint16_t atap_heads; /* 3: # of heads */
|
||||||
|
uint16_t __retired1[2]; /* 4-5: # of unform. bytes/track */
|
||||||
|
uint16_t atap_sectors; /* 6: # of sectors */
|
||||||
|
uint16_t __retired2[3];
|
||||||
|
|
||||||
|
uint8_t atap_serial[20]; /* 10-19: serial number */
|
||||||
|
uint16_t __retired3[2];
|
||||||
|
uint16_t __obsolete1;
|
||||||
|
uint8_t atap_revision[8]; /* 23-26: firmware revision */
|
||||||
|
uint8_t atap_model[40]; /* 27-46: model number */
|
||||||
|
uint16_t atap_multi; /* 47: maximum sectors per irq (ATA) */
|
||||||
|
uint16_t __reserved2;
|
||||||
|
uint8_t atap_vendor; /* 49: vendor */
|
||||||
|
uint8_t atap_capabilities1; /* 49: capability flags */
|
||||||
|
#define WDC_CAP_IORDY 0x0800
|
||||||
|
#define WDC_CAP_IORDY_DSBL 0x0400
|
||||||
|
#define WDC_CAP_LBA 0x0200
|
||||||
|
#define WDC_CAP_DMA 0x0100
|
||||||
|
#define ATA_CAP_STBY 0x2000
|
||||||
|
#define ATAPI_CAP_INTERL_DMA 0x8000
|
||||||
|
#define ATAPI_CAP_CMD_QUEUE 0x4000
|
||||||
|
#define ATAPI_CAP_OVERLP 0x2000
|
||||||
|
#define ATAPI_CAP_ATA_RST 0x1000
|
||||||
|
uint16_t atap_capabilities2; /* 50: capability flags (ATA) */
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
uint8_t __junk2;
|
||||||
|
uint8_t atap_oldpiotiming; /* 51: old PIO timing mode */
|
||||||
|
uint8_t __junk3;
|
||||||
|
uint8_t atap_olddmatiming; /* 52: old DMA timing mode (ATA) */
|
||||||
|
#else
|
||||||
|
uint8_t atap_oldpiotiming; /* 51: old PIO timing mode */
|
||||||
|
uint8_t __junk2;
|
||||||
|
uint8_t atap_olddmatiming; /* 52: old DMA timing mode (ATA) */
|
||||||
|
uint8_t __junk3;
|
||||||
|
#endif
|
||||||
|
uint16_t atap_extensions; /* 53: extensions supported */
|
||||||
|
#define WDC_EXT_UDMA_MODES 0x0004
|
||||||
|
#define WDC_EXT_MODES 0x0002
|
||||||
|
#define WDC_EXT_GEOM 0x0001
|
||||||
|
/* words 54-62 are ATA only */
|
||||||
|
uint16_t atap_curcylinders; /* 54: current logical cylinders */
|
||||||
|
uint16_t atap_curheads; /* 55: current logical heads */
|
||||||
|
uint16_t atap_cursectors; /* 56: current logical sectors/tracks */
|
||||||
|
uint16_t atap_curcapacity[2]; /* 57-58: current capacity */
|
||||||
|
uint8_t atap_curmulti; /* 59: current multi-sector setting */
|
||||||
|
uint8_t atap_curmulti_valid; /* 59: current multi-sector setting */
|
||||||
|
#define WDC_MULTI_VALID 0x0100
|
||||||
|
#define WDC_MULTI_MASK 0x00ff
|
||||||
|
uint32_t atap_capacity; /* 60-61: total capacity (LBA only) */
|
||||||
|
uint16_t __retired4;
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
uint8_t atap_dmamode_supp; /* 63: multiword DMA mode supported */
|
||||||
|
uint8_t atap_dmamode_act; /* multiword DMA mode active */
|
||||||
|
uint8_t atap_piomode_supp; /* 64: PIO mode supported */
|
||||||
|
uint8_t __junk4;
|
||||||
|
#else
|
||||||
|
uint8_t atap_dmamode_act; /* multiword DMA mode active */
|
||||||
|
uint8_t atap_dmamode_supp; /* 63: multiword DMA mode supported */
|
||||||
|
uint8_t __junk4;
|
||||||
|
uint8_t atap_piomode_supp; /* 64: PIO mode supported */
|
||||||
|
#endif
|
||||||
|
uint16_t atap_dmatiming_mimi; /* 65: minimum DMA cycle time */
|
||||||
|
uint16_t atap_dmatiming_recom; /* 66: recommended DMA cycle time */
|
||||||
|
uint16_t atap_piotiming; /* 67: mini PIO cycle time without FC */
|
||||||
|
uint16_t atap_piotiming_iordy; /* 68: mini PIO cycle time with IORDY FC */
|
||||||
|
uint16_t __reserved3[2];
|
||||||
|
/* words 71-72 are ATAPI only */
|
||||||
|
uint16_t atap_pkt_br; /* 71: time (ns) to bus release */
|
||||||
|
uint16_t atap_pkt_bsyclr; /* 72: tme to clear BSY after service */
|
||||||
|
uint16_t __reserved4[2];
|
||||||
|
uint16_t atap_queuedepth; /* 75: */
|
||||||
|
#define WDC_QUEUE_DEPTH_MASK 0x1f
|
||||||
|
uint16_t atap_sata_caps; /* 76: SATA capabilities */
|
||||||
|
#define SATA_SIGNAL_GEN1 0x0002 /* SATA Gen-1 signaling speed */
|
||||||
|
#define SATA_SIGNAL_GEN2 0x0004 /* SATA Gen-2 signaling speed */
|
||||||
|
#define SATA_NATIVE_CMDQ 0x0100 /* native command queuing */
|
||||||
|
#define SATA_HOST_PWR_MGMT 0x0200 /* power management (host) */
|
||||||
|
uint16_t atap_sata_reserved; /* 77: reserved */
|
||||||
|
uint16_t atap_sata_features_supp;/* 78: SATA features supported */
|
||||||
|
#define SATA_NONZERO_OFFSETS 0x0002 /* non-zero buffer offsets */
|
||||||
|
#define SATA_DMA_SETUP_AUTO 0x0004 /* DMA setup auto-activate */
|
||||||
|
#define SATA_DRIVE_PWR_MGMT 0x0008 /* power management (device) */
|
||||||
|
uint16_t atap_sata_features_en; /* 79: SATA features enabled */
|
||||||
|
uint16_t atap_ata_major; /* 80: Major version number */
|
||||||
|
#define WDC_VER_ATA1 0x0002
|
||||||
|
#define WDC_VER_ATA2 0x0004
|
||||||
|
#define WDC_VER_ATA3 0x0008
|
||||||
|
#define WDC_VER_ATA4 0x0010
|
||||||
|
#define WDC_VER_ATA5 0x0020
|
||||||
|
#define WDC_VER_ATA6 0x0040
|
||||||
|
#define WDC_VER_ATA7 0x0080
|
||||||
|
#define WDC_VER_ATA8 0x0100
|
||||||
|
#define WDC_VER_ATA9 0x0200
|
||||||
|
#define WDC_VER_ATA10 0x0400
|
||||||
|
#define WDC_VER_ATA11 0x0800
|
||||||
|
#define WDC_VER_ATA12 0x1000
|
||||||
|
#define WDC_VER_ATA13 0x2000
|
||||||
|
#define WDC_VER_ATA14 0x4000
|
||||||
|
uint16_t atap_ata_minor; /* 81: Minor version number */
|
||||||
|
uint16_t atap_cmd_set1; /* 82: command set supported */
|
||||||
|
#define WDC_CMD1_NOP 0x4000
|
||||||
|
#define WDC_CMD1_RB 0x2000
|
||||||
|
#define WDC_CMD1_WB 0x1000
|
||||||
|
#define WDC_CMD1_HPA 0x0400
|
||||||
|
#define WDC_CMD1_DVRST 0x0200
|
||||||
|
#define WDC_CMD1_SRV 0x0100
|
||||||
|
#define WDC_CMD1_RLSE 0x0080
|
||||||
|
#define WDC_CMD1_AHEAD 0x0040
|
||||||
|
#define WDC_CMD1_CACHE 0x0020
|
||||||
|
#define WDC_CMD1_PKT 0x0010
|
||||||
|
#define WDC_CMD1_PM 0x0008
|
||||||
|
#define WDC_CMD1_REMOV 0x0004
|
||||||
|
#define WDC_CMD1_SEC 0x0002
|
||||||
|
#define WDC_CMD1_SMART 0x0001
|
||||||
|
uint16_t atap_cmd_set2; /* 83: command set supported */
|
||||||
|
#define ATAPI_CMD2_FCE 0x2000 /* Flush Cache Ext supported */
|
||||||
|
#define ATAPI_CMD2_FC 0x1000 /* Flush Cache supported */
|
||||||
|
#define ATAPI_CMD2_DCO 0x0800 /* Device Configuration Overlay supported */
|
||||||
|
#define ATAPI_CMD2_48AD 0x0400 /* 48bit address supported */
|
||||||
|
#define ATAPI_CMD2_AAM 0x0200 /* Automatic Acoustic Management supported */
|
||||||
|
#define ATAPI_CMD2_SM 0x0100 /* Set Max security extension supported */
|
||||||
|
#define ATAPI_CMD2_SF 0x0040 /* Set Features subcommand required */
|
||||||
|
#define ATAPI_CMD2_PUIS 0x0020 /* Power up in standby supported */
|
||||||
|
#define WDC_CMD2_RMSN 0x0010
|
||||||
|
#define ATA_CMD2_APM 0x0008
|
||||||
|
#define ATA_CMD2_CFA 0x0004
|
||||||
|
#define ATA_CMD2_RWQ 0x0002
|
||||||
|
#define WDC_CMD2_DM 0x0001 /* Download Microcode supported */
|
||||||
|
uint16_t atap_cmd_ext; /* 84: command/features supp. ext. */
|
||||||
|
#define ATAPI_CMDE_MSER 0x0004 /* Media serial number supported */
|
||||||
|
#define ATAPI_CMDE_TEST 0x0002 /* SMART self-test supported */
|
||||||
|
#define ATAPI_CMDE_SLOG 0x0001 /* SMART error logging supported */
|
||||||
|
uint16_t atap_cmd1_en; /* 85: cmd/features enabled */
|
||||||
|
/* bits are the same as atap_cmd_set1 */
|
||||||
|
uint16_t atap_cmd2_en; /* 86: cmd/features enabled */
|
||||||
|
/* bits are the same as atap_cmd_set2 */
|
||||||
|
uint16_t atap_cmd_def; /* 87: cmd/features default */
|
||||||
|
/* bits are NOT the same as atap_cmd_ext */
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
uint8_t atap_udmamode_supp; /* 88: Ultra-DMA mode supported */
|
||||||
|
uint8_t atap_udmamode_act; /* Ultra-DMA mode active */
|
||||||
|
#else
|
||||||
|
uint8_t atap_udmamode_act; /* Ultra-DMA mode active */
|
||||||
|
uint8_t atap_udmamode_supp; /* 88: Ultra-DMA mode supported */
|
||||||
|
#endif
|
||||||
|
/* 89-92 are ATA-only */
|
||||||
|
uint16_t atap_seu_time; /* 89: Sec. Erase Unit compl. time */
|
||||||
|
uint16_t atap_eseu_time; /* 90: Enhanced SEU compl. time */
|
||||||
|
uint16_t atap_apm_val; /* 91: current APM value */
|
||||||
|
uint16_t atap_mpasswd_rev; /* 92: Master Password revision */
|
||||||
|
uint16_t atap_hwreset_res; /* 93: Hardware reset value */
|
||||||
|
#define ATA_HWRES_CBLID 0x2000 /* CBLID above Vih */
|
||||||
|
#define ATA_HWRES_D1_PDIAG 0x0800 /* Device 1 PDIAG detect OK */
|
||||||
|
#define ATA_HWRES_D1_CSEL 0x0400 /* Device 1 used CSEL for address */
|
||||||
|
#define ATA_HWRES_D1_JUMP 0x0200 /* Device 1 jumpered to address */
|
||||||
|
#define ATA_HWRES_D0_SEL 0x0040 /* Device 0 responds when Dev 1 selected */
|
||||||
|
#define ATA_HWRES_D0_DASP 0x0020 /* Device 0 DASP detect OK */
|
||||||
|
#define ATA_HWRES_D0_PDIAG 0x0010 /* Device 0 PDIAG detect OK */
|
||||||
|
#define ATA_HWRES_D0_DIAG 0x0008 /* Device 0 diag OK */
|
||||||
|
#define ATA_HWRES_D0_CSEL 0x0004 /* Device 0 used CSEL for address */
|
||||||
|
#define ATA_HWRES_D0_JUMP 0x0002 /* Device 0 jumpered to address */
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
uint8_t atap_acoustic_val; /* 94: Current acoustic level */
|
||||||
|
uint8_t atap_acoustic_def; /* recommended level */
|
||||||
|
#else
|
||||||
|
uint8_t atap_acoustic_def; /* recommended level */
|
||||||
|
uint8_t atap_acoustic_val; /* 94: Current acoustic level */
|
||||||
|
#endif
|
||||||
|
uint16_t __reserved6[5]; /* 95-99: reserved */
|
||||||
|
uint16_t atap_max_lba[4]; /* 100-103: Max. user LBA add */
|
||||||
|
uint16_t __reserved7[23]; /* 104-126: reserved */
|
||||||
|
uint16_t atap_rmsn_supp; /* 127: remov. media status notif. */
|
||||||
|
#define WDC_RMSN_SUPP_MASK 0x0003
|
||||||
|
#define WDC_RMSN_SUPP 0x0001
|
||||||
|
uint16_t atap_sec_st; /* 128: security status */
|
||||||
|
#define WDC_SEC_LEV_MAX 0x0100
|
||||||
|
#define WDC_SEC_ESE_SUPP 0x0020
|
||||||
|
#define WDC_SEC_EXP 0x0010
|
||||||
|
#define WDC_SEC_FROZEN 0x0008
|
||||||
|
#define WDC_SEC_LOCKED 0x0004
|
||||||
|
#define WDC_SEC_EN 0x0002
|
||||||
|
#define WDC_SEC_SUPP 0x0001
|
||||||
|
uint16_t __reserved8[31]; /* 129-159: vendor specific */
|
||||||
|
uint16_t atap_cfa_power; /* 160: CFA powermode */
|
||||||
|
#define ATAPI_CFA_MAX_MASK 0x0FFF
|
||||||
|
#define ATAPI_CFA_MODE1_DIS 0x1000 /* CFA Mode 1 Disabled */
|
||||||
|
#define ATAPI_CFA_MODE1_REQ 0x2000 /* CFA Mode 1 Required */
|
||||||
|
#define ATAPI_CFA_WORD160 0x8000 /* Word 160 supported */
|
||||||
|
uint16_t __reserved9[15]; /* 161-175: reserved for CFA */
|
||||||
|
uint8_t atap_media_serial[60]; /* 176-205: media serial number */
|
||||||
|
uint16_t __reserved10[49]; /* 206-254: reserved */
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
uint8_t atap_signature; /* 255: Signature */
|
||||||
|
uint8_t atap_checksum; /* Checksum */
|
||||||
|
#else
|
||||||
|
uint8_t atap_checksum; /* Checksum */
|
||||||
|
uint8_t atap_signature; /* 255: Signature */
|
||||||
|
#endif
|
||||||
} ATAIdentifyDevice;
|
} ATAIdentifyDevice;
|
||||||
|
|
||||||
|
#undef ATA_BYTE_ORDER
|
||||||
|
|
||||||
_Static_assert(sizeof(ATAIdentifyDevice) == 512);
|
_Static_assert(sizeof(ATAIdentifyDevice) == 512);
|
||||||
|
|
||||||
#endif /* __ATA_H__ */
|
#endif /* __ATA_H__ */
|
||||||
|
466
sys/dev/ide.c
466
sys/dev/ide.c
@ -8,6 +8,7 @@
|
|||||||
#include <sys/spinlock.h>
|
#include <sys/spinlock.h>
|
||||||
#include <sys/disk.h>
|
#include <sys/disk.h>
|
||||||
#include <sys/pci.h>
|
#include <sys/pci.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -25,15 +26,23 @@
|
|||||||
// #define IDE_SECONDARY_IRQ 15
|
// #define IDE_SECONDARY_IRQ 15
|
||||||
|
|
||||||
// Port Offsets
|
// Port Offsets
|
||||||
#define IDE_REG_DATAPORT 0
|
#define IDE_REG_DATAPORT 0x00
|
||||||
#define IDE_REG_FEATURES 1
|
#define IDE_REG_ERROR 0x01
|
||||||
#define IDE_REG_SECTORCOUNT 2
|
#define IDE_REG_FEATURES 0x01
|
||||||
#define IDE_REG_LBALOW 3
|
#define IDE_REG_SECCOUNT0 0x02
|
||||||
#define IDE_REG_LBAMID 4
|
#define IDE_REG_LBA0 0x03
|
||||||
#define IDE_REG_LBAHIGH 5
|
#define IDE_REG_LBA1 0x04
|
||||||
#define IDE_REG_DRIVE 6
|
#define IDE_REG_LBA2 0x05
|
||||||
#define IDE_REG_COMMAND 7 /* Write */
|
#define IDE_REG_HDDEVSEL 0x06
|
||||||
#define IDE_REG_STATUS 7 /* Read */
|
#define IDE_REG_COMMAND 0x07
|
||||||
|
#define IDE_REG_STATUS 0x07
|
||||||
|
#define IDE_REG_SECCOUNT1 0x08
|
||||||
|
#define IDE_REG_LBA3 0x09
|
||||||
|
#define IDE_REG_LBA4 0x0A
|
||||||
|
#define IDE_REG_LBA5 0x0B
|
||||||
|
#define IDE_REG_CONTROL 0x0C
|
||||||
|
#define IDE_REG_ALTSTATUS 0x0C
|
||||||
|
#define IDE_REG_DEVADDRESS 0x0D
|
||||||
|
|
||||||
#define IDE_CTRLREG_OFFSET 2
|
#define IDE_CTRLREG_OFFSET 2
|
||||||
|
|
||||||
@ -104,21 +113,31 @@ ide_write_reg8(const IDE * ide, UNUSED unsigned int channel, unsigned int offset
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ide_read_buf32(const IDE * ide, UNUSED unsigned int channel, void * buffer, size_t times)
|
ide_read_buf16(const IDE * ide, UNUSED unsigned int channel, void * buffer, size_t times)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < times ; i++) {
|
for(unsigned int i = 0; i < times ; i++) {
|
||||||
volatile uint32_t * read = ide->primary_base + IDE_REG_DATAPORT;
|
volatile uint16_t * read = ide->primary_base + IDE_REG_DATAPORT;
|
||||||
uint32_t data = * read;
|
uint16_t data = * read;
|
||||||
memcpy(buffer, &data, sizeof(uint32_t));
|
memcpy(buffer, &data, sizeof(uint16_t));
|
||||||
|
buffer = buffer + sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static inline uint8_t
|
static inline void
|
||||||
// ide_read_ctrl(const IDE * ide, UNUSED unsigned int channel)
|
ide_write_buf16(const IDE * ide, UNUSED unsigned int channel, void * buffer, size_t times)
|
||||||
// {
|
{
|
||||||
// volatile uint8_t * read = ide->primary_ctl + IDE_CTRLREG_OFFSET;
|
for(unsigned int i = 0; i < times ; i++) {
|
||||||
// return *read;
|
volatile uint16_t * read = ide->primary_base + IDE_REG_DATAPORT;
|
||||||
// }
|
*read = *(uint16_t *)(buffer + i * sizeof(uint16_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static inline uint8_t
|
||||||
|
ide_read_ctrl(const IDE * ide, UNUSED unsigned int channel)
|
||||||
|
{
|
||||||
|
volatile uint8_t * read = ide->primary_ctl + IDE_CTRLREG_OFFSET;
|
||||||
|
return *read;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ide_write_ctrl(const IDE * ide, UNUSED unsigned int channel, uint8_t data)
|
ide_write_ctrl(const IDE * ide, UNUSED unsigned int channel, uint8_t data)
|
||||||
@ -142,7 +161,7 @@ IDE_Init(PCIDevice * dev)
|
|||||||
Panic("IDE controller does not support memory mapped IO.\n");
|
Panic("IDE controller does not support memory mapped IO.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
kprintf("Initializing: IDE controller, progif = 0x%x, bar0 = 0x%x, bar1 = 0x%x\n", dev->progif, dev->bars[0].base, dev->bars[1].base);
|
Log(ide, "Progif = 0x%x, BAR0 = 0x%x, BAR1 = 0x%x\n", dev->progif, dev->bars[0].base, dev->bars[1].base);
|
||||||
// ide primary base
|
// ide primary base
|
||||||
primary.primary_base = (void *)DEVPA2VA(dev->bar_mappings[0]);
|
primary.primary_base = (void *)DEVPA2VA(dev->bar_mappings[0]);
|
||||||
primary.primary_ctl = (void *)DEVPA2VA(dev->bar_mappings[1]);
|
primary.primary_ctl = (void *)DEVPA2VA(dev->bar_mappings[1]);
|
||||||
@ -150,7 +169,7 @@ IDE_Init(PCIDevice * dev)
|
|||||||
SPINLOCK_TYPE_NORMAL);
|
SPINLOCK_TYPE_NORMAL);
|
||||||
|
|
||||||
if (!IDE_HasController(&primary)) {
|
if (!IDE_HasController(&primary)) {
|
||||||
kprintf("IDE: No controller detected\n");
|
Warning(ide, "IDE: No controller detected\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,12 +200,12 @@ IDEWaitForBusy(IDE *ide)
|
|||||||
bool
|
bool
|
||||||
IDE_HasController(IDE *ide)
|
IDE_HasController(IDE *ide)
|
||||||
{
|
{
|
||||||
ide_write_reg8(ide, 0, IDE_REG_LBALOW, 0x41);
|
ide_write_reg8(ide, 0, IDE_REG_LBA0, 0x41);
|
||||||
ide_write_reg8(ide, 0, IDE_REG_LBAMID, 0x4D);
|
ide_write_reg8(ide, 0, IDE_REG_LBA1, 0x4D);
|
||||||
|
|
||||||
if (ide_read_reg8(ide, 0, IDE_REG_LBALOW) != 0x41)
|
if (ide_read_reg8(ide, 0, IDE_REG_LBA0) != 0x41)
|
||||||
return false;
|
return false;
|
||||||
if (ide_read_reg8(ide, 0, IDE_REG_LBAMID) != 0x4D)
|
if (ide_read_reg8(ide, 0, IDE_REG_LBA1) != 0x4D)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -207,7 +226,7 @@ IDE_Reset(IDE *ide)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
UNUSED static void
|
||||||
IDE_SwapAndTruncateString(char *str, int len)
|
IDE_SwapAndTruncateString(char *str, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -243,7 +262,7 @@ IDE_Identify(IDE *ide, int drive)
|
|||||||
else
|
else
|
||||||
driveCode = 0xB0;
|
driveCode = 0xB0;
|
||||||
|
|
||||||
ide_write_reg8(ide, 0, IDE_REG_DRIVE, driveCode);
|
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
|
||||||
|
|
||||||
status = IDEWaitForBusy(ide);
|
status = IDEWaitForBusy(ide);
|
||||||
if ((status & IDE_STATUS_ERR) != 0) {
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
@ -277,28 +296,32 @@ IDE_Identify(IDE *ide, int drive)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ide_read_buf32(ide, 0, &ident, sizeof(struct ATAIdentifyDevice) / sizeof(uint32_t));
|
ide_read_buf16(ide, 0, &ident, sizeof(ATAIdentifyDevice) / sizeof(uint16_t));
|
||||||
|
|
||||||
// Cleanup model and serial for printing
|
// Cleanup model and serial for printing
|
||||||
char model[41];
|
char model[41];
|
||||||
char serial[21];
|
char serial[21];
|
||||||
|
|
||||||
memcpy(&model[0], &ident.model[0], 40);
|
memcpy(&model[0], &ident.atap_model[0], 40);
|
||||||
model[40] = '\0';
|
model[40] = '\0';
|
||||||
IDE_SwapAndTruncateString(&model[0], 40);
|
//IDE_SwapAndTruncateString(&model[0], 40);
|
||||||
|
|
||||||
memcpy(&serial[0], &ident.serial[0], 20);
|
memcpy(&serial[0], &ident.atap_serial[0], 20);
|
||||||
serial[20] = '\0';
|
serial[20] = '\0';
|
||||||
IDE_SwapAndTruncateString(&serial[0], 20);
|
//IDE_SwapAndTruncateString(&serial[0], 20);
|
||||||
|
|
||||||
kprintf("Drive %d Model: %s Serial: %s\n", drive, model, serial);
|
Log(ide, "Drive %d Model: \"%s\" Capabilities: 0x%x\n", drive, model, ident.atap_capabilities1);
|
||||||
kprintf("Drive %d %lu Sectors (%llu MBs)\n",
|
// XXX: check capabilities
|
||||||
drive, ident.lbaSectors, ident.lbaSectors / 2048ULL);
|
Log(ide, "Drive %d: %u Sectors (%lu Bytes, %lu KiB, %lu MiB)\n",
|
||||||
|
drive, ident.atap_capacity,
|
||||||
|
(uint64_t)ident.atap_capacity * IDE_SECTOR_SIZE,
|
||||||
|
(uint64_t)ident.atap_capacity * IDE_SECTOR_SIZE / 1024,
|
||||||
|
(uint64_t)ident.atap_capacity * IDE_SECTOR_SIZE / 1024 / 1024);
|
||||||
|
|
||||||
primaryDrives[drive].ide = &primary;
|
primaryDrives[drive].ide = &primary;
|
||||||
primaryDrives[drive].drive = drive;
|
primaryDrives[drive].drive = drive;
|
||||||
primaryDrives[drive].lba48 = (ident.lbaSectors > (1 << 24));
|
primaryDrives[drive].lba48 = (ident.atap_capacity > (1 << 24));
|
||||||
primaryDrives[drive].size = ident.lbaSectors;
|
primaryDrives[drive].size = ident.atap_capacity;
|
||||||
|
|
||||||
// Register Disk
|
// Register Disk
|
||||||
Disk *disk = PAlloc_AllocPage();
|
Disk *disk = PAlloc_AllocPage();
|
||||||
@ -310,231 +333,232 @@ IDE_Identify(IDE *ide, int drive)
|
|||||||
disk->ctrlNo = 0;
|
disk->ctrlNo = 0;
|
||||||
disk->diskNo = drive;
|
disk->diskNo = drive;
|
||||||
disk->sectorSize = IDE_SECTOR_SIZE;
|
disk->sectorSize = IDE_SECTOR_SIZE;
|
||||||
disk->sectorCount = ident.lbaSectors;
|
disk->sectorCount = ident.atap_capacity;
|
||||||
disk->diskSize = IDE_SECTOR_SIZE * ident.lbaSectors;
|
disk->diskSize = IDE_SECTOR_SIZE * ident.atap_capacity;
|
||||||
// disk->read = IDE_Read;
|
disk->read = IDE_Read;
|
||||||
// disk->write = IDE_Write;
|
disk->write = IDE_Write;
|
||||||
// disk->flush = IDE_Flush;
|
disk->flush = IDE_Flush;
|
||||||
|
|
||||||
// Disk_AddDisk(disk);
|
Disk_AddDisk(disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int
|
int
|
||||||
// IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
||||||
// {
|
{
|
||||||
// int i;
|
unsigned int i;
|
||||||
// int status;
|
int status;
|
||||||
// IDEDrive *idedrive;
|
IDEDrive *idedrive;
|
||||||
|
|
||||||
// idedrive = disk->handle;
|
idedrive = disk->handle;
|
||||||
|
|
||||||
// for (i = 0; i < sga->len; i++) {
|
for (i = 0; i < sga->len; i++) {
|
||||||
// status = IDE_ReadOne(idedrive,
|
status = IDE_ReadOne(idedrive,
|
||||||
// buf,
|
buf,
|
||||||
// sga->entries[i].offset / 512,
|
sga->entries[i].offset / 512,
|
||||||
// sga->entries[i].length / 512);
|
sga->entries[i].length / 512);
|
||||||
// buf += sga->entries[i].length;
|
buf += sga->entries[i].length;
|
||||||
// if (status < 0)
|
if (status < 0)
|
||||||
// return status;
|
return status;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return 0;
|
return 0;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// int
|
int
|
||||||
// IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
||||||
// {
|
{
|
||||||
// int i;
|
unsigned int i;
|
||||||
// int status;
|
int status;
|
||||||
// IDEDrive *idedrive;
|
IDEDrive *idedrive;
|
||||||
|
|
||||||
// idedrive = disk->handle;
|
idedrive = disk->handle;
|
||||||
|
|
||||||
// for (i = 0; i < sga->len; i++) {
|
for (i = 0; i < sga->len; i++) {
|
||||||
// status = IDE_WriteOne(idedrive,
|
status = IDE_WriteOne(idedrive,
|
||||||
// buf,
|
buf,
|
||||||
// sga->entries[i].offset / 512,
|
sga->entries[i].offset / 512,
|
||||||
// sga->entries[i].length / 512);
|
sga->entries[i].length / 512);
|
||||||
// buf += sga->entries[i].length;
|
buf += sga->entries[i].length;
|
||||||
// if (status < 0)
|
if (status < 0)
|
||||||
// return status;
|
return status;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return 0;
|
return 0;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// int
|
int
|
||||||
// IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
|
||||||
// {
|
{
|
||||||
// uint8_t driveCode;
|
uint8_t driveCode;
|
||||||
// IDE *ide;
|
IDE *ide;
|
||||||
// IDEDrive *idedrive;
|
IDEDrive *idedrive;
|
||||||
|
|
||||||
// idedrive = disk->handle;
|
idedrive = disk->handle;
|
||||||
// ide = idedrive->ide;
|
ide = idedrive->ide;
|
||||||
|
|
||||||
// if (idedrive->drive == 0)
|
if (idedrive->drive == 0)
|
||||||
// driveCode = 0xA0;
|
driveCode = 0xA0;
|
||||||
// else
|
else
|
||||||
// driveCode = 0xB0;
|
driveCode = 0xB0;
|
||||||
|
|
||||||
// Spinlock_Lock(&ide->lock);
|
Spinlock_Lock(&ide->lock);
|
||||||
// outb(ide->base + IDE_DRIVE, driveCode);
|
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
|
||||||
// outb(ide->base + IDE_COMMAND, IDE_CMD_FLUSH);
|
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_FLUSH);
|
||||||
|
|
||||||
// IDEWaitForBusy(ide, false);
|
IDEWaitForBusy(ide);
|
||||||
// Spinlock_Unlock(&ide->lock);
|
Spinlock_Unlock(&ide->lock);
|
||||||
|
|
||||||
// return 0;
|
return 0;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// int
|
int
|
||||||
// IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||||
// {
|
{
|
||||||
// bool lba48 = false;
|
bool lba48 = false;
|
||||||
// uint8_t driveCode;
|
uint8_t driveCode;
|
||||||
// uint8_t status;
|
uint8_t status;
|
||||||
// IDE *ide = drive->ide;
|
IDE *ide = drive->ide;
|
||||||
|
|
||||||
// DLOG(ide, "read %llx %llx\n", off, len);
|
DLOG(ide, "read offset = 0x%lx, len = 0x%lx.\n", off, len);
|
||||||
|
|
||||||
// ASSERT(drive->drive == 0 || drive->drive == 1);
|
ASSERT(drive->drive == 0 || drive->drive == 1);
|
||||||
|
|
||||||
// if (drive->drive == 0)
|
if (drive->drive == 0)
|
||||||
// driveCode = lba48 ? 0x40 : 0xE0;
|
driveCode = lba48 ? 0x40 : 0xE0;
|
||||||
// else
|
else
|
||||||
// driveCode = lba48 ? 0x50 : 0xF0;
|
driveCode = lba48 ? 0x50 : 0xF0;
|
||||||
|
|
||||||
// ASSERT(len < 0x10000);
|
ASSERT(len < 0x10000);
|
||||||
|
|
||||||
// Spinlock_Lock(&ide->lock);
|
Spinlock_Lock(&ide->lock);
|
||||||
// if (driveCode != ide->lastDriveCode) {
|
if (driveCode != ide->lastDriveCode) {
|
||||||
// outb(ide->base + IDE_DRIVE, driveCode);
|
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
|
||||||
|
|
||||||
// // Need to wait for select to complete
|
// Need to wait for select to complete
|
||||||
// status = IDEWaitForBusy(ide, true);
|
status = IDEWaitForBusy(ide);
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
// Spinlock_Unlock(&ide->lock);
|
Spinlock_Unlock(&ide->lock);
|
||||||
// Log(ide, "Error selecting drive %d\n", drive->drive);
|
Log(ide, "Error selecting drive %d\n", drive->drive);
|
||||||
// return -1;
|
return EIO;
|
||||||
// }
|
}
|
||||||
// ide->lastDriveCode = driveCode;
|
ide->lastDriveCode = driveCode;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (lba48) {
|
if (lba48) {
|
||||||
// outb(ide->base + IDE_SECTORCOUNT, len >> 8);
|
ide_write_reg8(ide, 0, IDE_REG_SECCOUNT1, len >> 8);
|
||||||
// outb(ide->base + IDE_LBALOW, off >> 24);
|
ide_write_reg8(ide, 0, IDE_REG_LBA3, off >> 24);
|
||||||
// outb(ide->base + IDE_LBAMID, off >> 32);
|
ide_write_reg8(ide, 0, IDE_REG_LBA4, off >> 32);
|
||||||
// outb(ide->base + IDE_LBAHIGH, off >> 40);
|
ide_write_reg8(ide, 0, IDE_REG_LBA5, off >> 40);
|
||||||
// }
|
}
|
||||||
// outb(ide->base + IDE_SECTORCOUNT, len);
|
|
||||||
// outb(ide->base + IDE_LBALOW, off & 0xff);
|
|
||||||
// outb(ide->base + IDE_LBAMID, (off >> 8) & 0xff);
|
|
||||||
// outb(ide->base + IDE_LBAHIGH, (off >> 16) & 0xff);
|
|
||||||
|
|
||||||
// if (lba48)
|
ide_write_reg8(ide, 0, IDE_REG_SECCOUNT0, len);
|
||||||
// outb(ide->base + IDE_COMMAND, IDE_CMD_READ_EXT);
|
ide_write_reg8(ide, 0, IDE_REG_LBA0, off & 0xff);
|
||||||
// else
|
ide_write_reg8(ide, 0, IDE_REG_LBA1, (off >> 8) & 0xff);
|
||||||
// outb(ide->base + IDE_COMMAND, IDE_CMD_READ);
|
ide_write_reg8(ide, 0, IDE_REG_LBA2, (off >> 16) & 0xff);
|
||||||
|
|
||||||
// status = IDEWaitForBusy(ide, false);
|
if (lba48)
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_READ_EXT);
|
||||||
// Spinlock_Unlock(&ide->lock);
|
else
|
||||||
// Log(ide, "Error trying read from drive %d\n", drive->drive);
|
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_READ);
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int sectors;
|
status = IDEWaitForBusy(ide);
|
||||||
// for (sectors = 0; sectors < len; sectors++)
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
// {
|
Spinlock_Unlock(&ide->lock);
|
||||||
// uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
|
Log(ide, "Error trying read from drive %d\n", drive->drive);
|
||||||
// insw(ide->base + IDE_DATAPORT, b, 256);
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
// status = IDEWaitForBusy(ide, true);
|
unsigned int sectors;
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
for (sectors = 0; sectors < len; sectors++)
|
||||||
// Spinlock_Unlock(&ide->lock);
|
{
|
||||||
// Log(ide, "Error reading from drive %d\n", drive->drive);
|
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
|
||||||
// return -1;
|
ide_read_buf16(ide, 0, b, IDE_SECTOR_SIZE / sizeof(uint16_t));
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Spinlock_Unlock(&ide->lock);
|
|
||||||
|
|
||||||
// return 0;
|
status = IDEWaitForBusy(ide);
|
||||||
// }
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
|
Spinlock_Unlock(&ide->lock);
|
||||||
|
Log(ide, "Error reading from drive %d\n", drive->drive);
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spinlock_Unlock(&ide->lock);
|
||||||
|
|
||||||
// int
|
return 0;
|
||||||
// IDE_WriteOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
}
|
||||||
// {
|
|
||||||
// bool lba48 = false;
|
|
||||||
// uint8_t driveCode;
|
|
||||||
// uint8_t status;
|
|
||||||
// IDE *ide = drive->ide;
|
|
||||||
|
|
||||||
// DLOG(ide, "read %llx %llx\n", off, len);
|
int
|
||||||
|
IDE_WriteOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
|
||||||
|
{
|
||||||
|
bool lba48 = false;
|
||||||
|
uint8_t driveCode;
|
||||||
|
uint8_t status;
|
||||||
|
IDE *ide = drive->ide;
|
||||||
|
|
||||||
// ASSERT(drive->drive == 0 || drive->drive == 1);
|
DLOG(ide, "write offset = 0x%lx, len = 0x%lx.\n", off, len);
|
||||||
|
|
||||||
// if (drive->drive == 0)
|
ASSERT(drive->drive == 0 || drive->drive == 1);
|
||||||
// driveCode = lba48 ? 0x40 : 0xE0;
|
|
||||||
// else
|
|
||||||
// driveCode = lba48 ? 0x50 : 0xF0;
|
|
||||||
|
|
||||||
// ASSERT(len < 0x10000);
|
if (drive->drive == 0)
|
||||||
|
driveCode = lba48 ? 0x40 : 0xE0;
|
||||||
|
else
|
||||||
|
driveCode = lba48 ? 0x50 : 0xF0;
|
||||||
|
|
||||||
// Spinlock_Lock(&ide->lock);
|
ASSERT(len < 0x10000);
|
||||||
// if (driveCode != ide->lastDriveCode) {
|
|
||||||
// outb(ide->base + IDE_DRIVE, driveCode);
|
|
||||||
|
|
||||||
// // Need to wait for select to complete
|
Spinlock_Lock(&ide->lock);
|
||||||
// status = IDEWaitForBusy(ide, true);
|
if (driveCode != ide->lastDriveCode) {
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
|
||||||
// Spinlock_Unlock(&ide->lock);
|
|
||||||
// Log(ide, "Error selecting drive %d\n", drive->drive);
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
// ide->lastDriveCode = driveCode;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (lba48) {
|
// Need to wait for select to complete
|
||||||
// outb(ide->base + IDE_SECTORCOUNT, len >> 8);
|
status = IDEWaitForBusy(ide);
|
||||||
// outb(ide->base + IDE_LBALOW, off >> 24);
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
// outb(ide->base + IDE_LBAMID, off >> 32);
|
Spinlock_Unlock(&ide->lock);
|
||||||
// outb(ide->base + IDE_LBAHIGH, off >> 40);
|
Log(ide, "Error selecting drive %d\n", drive->drive);
|
||||||
// }
|
return EIO;
|
||||||
// outb(ide->base + IDE_SECTORCOUNT, len);
|
}
|
||||||
// outb(ide->base + IDE_LBALOW, off & 0xff);
|
ide->lastDriveCode = driveCode;
|
||||||
// outb(ide->base + IDE_LBAMID, (off >> 8) & 0xff);
|
}
|
||||||
// outb(ide->base + IDE_LBAHIGH, (off >> 16) & 0xff);
|
|
||||||
|
|
||||||
// if (lba48)
|
if (lba48) {
|
||||||
// outb(ide->base + IDE_COMMAND, IDE_CMD_WRITE_EXT);
|
ide_write_reg8(ide, 0, IDE_REG_SECCOUNT1, len >> 8);
|
||||||
// else
|
ide_write_reg8(ide, 0, IDE_REG_LBA3, off >> 24);
|
||||||
// outb(ide->base + IDE_COMMAND, IDE_CMD_WRITE);
|
ide_write_reg8(ide, 0, IDE_REG_LBA4, off >> 32);
|
||||||
|
ide_write_reg8(ide, 0, IDE_REG_LBA5, off >> 40);
|
||||||
|
}
|
||||||
|
ide_write_reg8(ide, 0, IDE_REG_SECCOUNT0, len);
|
||||||
|
ide_write_reg8(ide, 0, IDE_REG_LBA0, off & 0xff);
|
||||||
|
ide_write_reg8(ide, 0, IDE_REG_LBA1, (off >> 8) & 0xff);
|
||||||
|
ide_write_reg8(ide, 0, IDE_REG_LBA2, (off >> 16) & 0xff);
|
||||||
|
|
||||||
// status = IDEWaitForBusy(ide, false);
|
if (lba48)
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_WRITE_EXT);
|
||||||
// Spinlock_Unlock(&ide->lock);
|
else
|
||||||
// Log(ide, "Error trying read from drive %d\n", drive->drive);
|
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_WRITE);
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int sectors;
|
status = IDEWaitForBusy(ide);
|
||||||
// for (sectors = 0; sectors < len; sectors++)
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
// {
|
Spinlock_Unlock(&ide->lock);
|
||||||
// uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
|
Log(ide, "Error trying read from drive %d\n", drive->drive);
|
||||||
// outsw(ide->base + IDE_DATAPORT, b, 256);
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
// status = IDEWaitForBusy(ide, true);
|
unsigned int sectors;
|
||||||
// if ((status & IDE_STATUS_ERR) != 0) {
|
for (sectors = 0; sectors < len; sectors++)
|
||||||
// Spinlock_Unlock(&ide->lock);
|
{
|
||||||
// Log(ide, "Error reading from drive %d\n", drive->drive);
|
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
|
||||||
// return -1;
|
ide_write_buf16(ide, 0, b, IDE_SECTOR_SIZE / sizeof(uint16_t));
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Spinlock_Unlock(&ide->lock);
|
|
||||||
|
|
||||||
// // XXX: Flush cache ...
|
status = IDEWaitForBusy(ide);
|
||||||
|
if ((status & IDE_STATUS_ERR) != 0) {
|
||||||
|
Spinlock_Unlock(&ide->lock);
|
||||||
|
Log(ide, "Error reading from drive %d\n", drive->drive);
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spinlock_Unlock(&ide->lock);
|
||||||
|
|
||||||
// return 0;
|
// XXX: Flush cache ...
|
||||||
// }
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -42,12 +42,12 @@ NO_RETURN void Debug_Assert(const char *fmt, ...);
|
|||||||
#define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__)
|
#define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__)
|
||||||
// Normal Logging
|
// Normal Logging
|
||||||
#define Log(_module, _format, ...) \
|
#define Log(_module, _format, ...) \
|
||||||
if (SYSCTL_GETINT(log_##_module) >= 1) { \
|
if (SYSCTL_GETINT(log_##_module) >= 1 || 1) { \
|
||||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||||
}
|
}
|
||||||
// Debug Logging
|
// Debug Logging
|
||||||
#define DLOG(_module, _format, ...) \
|
#define DLOG(_module, _format, ...) \
|
||||||
if (SYSCTL_GETINT(log_##_module) >= 5) { \
|
if (SYSCTL_GETINT(log_##_module) >= 5 || 1) { \
|
||||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||||
}
|
}
|
||||||
// Verbose Logging
|
// Verbose Logging
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \
|
SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \
|
||||||
SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
|
SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
|
||||||
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
|
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
|
||||||
SYSCTL_INT(log_vfs, SYSCTL_FLAG_RW, "VFS log level", 0)
|
SYSCTL_INT(log_vfs, SYSCTL_FLAG_RW, "VFS log level", 0) \
|
||||||
|
SYSCTL_INT(log_bufcache, SYSCTL_FLAG_RW, "Buffer cache log level", 0)
|
||||||
|
|
||||||
#define SYSCTL_STR_MAXLENGTH 128
|
#define SYSCTL_STR_MAXLENGTH 128
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void
|
|||||||
BufCache_Init()
|
BufCache_Init()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
Log(bufcache, "Initializing ...\n");
|
||||||
Spinlock_Init(&cacheLock, "BufCache Lock", SPINLOCK_TYPE_NORMAL);
|
Spinlock_Init(&cacheLock, "BufCache Lock", SPINLOCK_TYPE_NORMAL);
|
||||||
|
|
||||||
diskBuf = XMem_New();
|
diskBuf = XMem_New();
|
||||||
@ -78,6 +78,8 @@ BufCache_Init()
|
|||||||
cacheHit = 0;
|
cacheHit = 0;
|
||||||
cacheMiss = 0;
|
cacheMiss = 0;
|
||||||
cacheAlloc = 0;
|
cacheAlloc = 0;
|
||||||
|
|
||||||
|
Log(bufcache, "Initialized!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +36,7 @@ int
|
|||||||
VFS_MountRoot(Disk *rootDisk)
|
VFS_MountRoot(Disk *rootDisk)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
Log(vfs, "Mounting root...\n");
|
||||||
Spinlock_Init(&vfsLock, "VFS Lock", SPINLOCK_TYPE_NORMAL);
|
Spinlock_Init(&vfsLock, "VFS Lock", SPINLOCK_TYPE_NORMAL);
|
||||||
|
|
||||||
Slab_Init(&vfsSlab, "VFS Slab", sizeof(VFS), 16);
|
Slab_Init(&vfsSlab, "VFS Slab", sizeof(VFS), 16);
|
||||||
@ -49,7 +49,7 @@ VFS_MountRoot(Disk *rootDisk)
|
|||||||
status = rootFS->op->getroot(rootFS, &rootNode);
|
status = rootFS->op->getroot(rootFS, &rootNode);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
Panic("Failed to get root VNode\n");
|
Panic("Failed to get root VNode\n");
|
||||||
|
Log(vfs, "Root mounted!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user