This commit is contained in:
quackerd 2024-11-11 05:14:06 -05:00
parent 977951fd95
commit a1bf1cd7b4
7 changed files with 493 additions and 255 deletions

View File

@ -110,10 +110,8 @@ void Machine_Init()
// 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
disable_interrupts();
PTimer_Init();
KTimer_Init();
enable_interrupts();
Thread_Init();
@ -132,9 +130,6 @@ void Machine_Init()
PCI_Init(); // PCI BUS
BufCache_Init();
while(1){
hlt();
}
/*
* Open the primary disk and mount the root file system
*/
@ -145,6 +140,10 @@ void Machine_Init()
Critical_Exit();
while(1){
hlt();
}
/*
* Create the idle thread
*/

View File

@ -5,31 +5,243 @@
#ifndef __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
uint8_t serial[20]; // 10-19 - Serial
uint16_t _rsvd1[3]; // 20-22
uint8_t firmware[8]; // 23-26 - Firmware
uint8_t model[40]; // 27-46 - Model
uint16_t _rsvd2[16]; // 47-62 X
uint16_t dmaMode; // 63 - DMA Mode
uint16_t _rsvd3[11]; // 64-74 X
uint16_t queueDepth; // 75 - Queue Depth
uint16_t sataCap; // 76 - SATA Capabilities
uint16_t ncqCap; // 77 - NCQ Capabilities
uint16_t _rsvd4[8]; // 78-85
uint16_t deviceFlags; // 86 - Device Flags (48-bit Addressing)
uint16_t deviceFlags2; // 87 - Device Flags 2 (SMART)
uint16_t udmaMode; // 88 - Ultra DMA Mode
uint16_t _rsvd5[11]; // 89-99
uint64_t lbaSectors; // 100-103 - User Addressable Logical Sectors
uint16_t _rsvd6[2]; // 104-105
uint16_t sectorSize; // 106 - Physical Sector Size
uint16_t _rsvd7[148]; // 107-254
uint16_t chksum; // 255 - Checksum
/* drive info */
uint16_t atap_config; /* 0: general configuration */
#define WDC_CFG_ATAPI_MASK 0xc000
#define WDC_CFG_ATAPI 0x8000
#define ATA_CFG_REMOVABLE 0x0080
#define ATA_CFG_FIXED 0x0040
#define ATAPI_CFG_TYPE_MASK 0x1f00
#define ATAPI_CFG_TYPE(x) (((x) & ATAPI_CFG_TYPE_MASK) >> 8)
#define ATAPI_CFG_TYPE_DIRECT 0x00
#define ATAPI_CFG_TYPE_SEQUENTIAL 0x01
#define ATAPI_CFG_TYPE_CDROM 0x05
#define ATAPI_CFG_TYPE_OPTICAL 0x07
#define ATAPI_CFG_TYPE_NODEVICE 0x1F
#define ATAPI_CFG_REMOV 0x0080
#define ATAPI_CFG_DRQ_MASK 0x0060
#define ATAPI_CFG_STD_DRQ 0x0000
#define ATAPI_CFG_IRQ_DRQ 0x0020
#define ATAPI_CFG_ACCEL_DRQ 0x0040
#define ATAPI_CFG_CMD_MASK 0x0003
#define ATAPI_CFG_CMD_12 0x0000
#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;
#undef ATA_BYTE_ORDER
_Static_assert(sizeof(ATAIdentifyDevice) == 512);
#endif /* __ATA_H__ */

View File

@ -8,6 +8,7 @@
#include <sys/spinlock.h>
#include <sys/disk.h>
#include <sys/pci.h>
#include <errno.h>
#include <machine/pmap.h>
#include "ata.h"
@ -25,15 +26,23 @@
// #define IDE_SECONDARY_IRQ 15
// Port Offsets
#define IDE_REG_DATAPORT 0
#define IDE_REG_FEATURES 1
#define IDE_REG_SECTORCOUNT 2
#define IDE_REG_LBALOW 3
#define IDE_REG_LBAMID 4
#define IDE_REG_LBAHIGH 5
#define IDE_REG_DRIVE 6
#define IDE_REG_COMMAND 7 /* Write */
#define IDE_REG_STATUS 7 /* Read */
#define IDE_REG_DATAPORT 0x00
#define IDE_REG_ERROR 0x01
#define IDE_REG_FEATURES 0x01
#define IDE_REG_SECCOUNT0 0x02
#define IDE_REG_LBA0 0x03
#define IDE_REG_LBA1 0x04
#define IDE_REG_LBA2 0x05
#define IDE_REG_HDDEVSEL 0x06
#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
@ -104,21 +113,31 @@ ide_write_reg8(const IDE * ide, UNUSED unsigned int channel, unsigned int offset
}
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++) {
volatile uint32_t * read = ide->primary_base + IDE_REG_DATAPORT;
uint32_t data = * read;
memcpy(buffer, &data, sizeof(uint32_t));
volatile uint16_t * read = ide->primary_base + IDE_REG_DATAPORT;
uint16_t data = * read;
memcpy(buffer, &data, sizeof(uint16_t));
buffer = buffer + sizeof(uint16_t);
}
}
// 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
ide_write_buf16(const IDE * ide, UNUSED unsigned int channel, void * buffer, size_t times)
{
for(unsigned int i = 0; i < times ; i++) {
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
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");
}
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
primary.primary_base = (void *)DEVPA2VA(dev->bar_mappings[0]);
primary.primary_ctl = (void *)DEVPA2VA(dev->bar_mappings[1]);
@ -150,7 +169,7 @@ IDE_Init(PCIDevice * dev)
SPINLOCK_TYPE_NORMAL);
if (!IDE_HasController(&primary)) {
kprintf("IDE: No controller detected\n");
Warning(ide, "IDE: No controller detected\n");
return;
}
@ -181,12 +200,12 @@ IDEWaitForBusy(IDE *ide)
bool
IDE_HasController(IDE *ide)
{
ide_write_reg8(ide, 0, IDE_REG_LBALOW, 0x41);
ide_write_reg8(ide, 0, IDE_REG_LBAMID, 0x4D);
ide_write_reg8(ide, 0, IDE_REG_LBA0, 0x41);
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;
if (ide_read_reg8(ide, 0, IDE_REG_LBAMID) != 0x4D)
if (ide_read_reg8(ide, 0, IDE_REG_LBA1) != 0x4D)
return false;
return true;
@ -207,7 +226,7 @@ IDE_Reset(IDE *ide)
}
}
void
UNUSED static void
IDE_SwapAndTruncateString(char *str, int len)
{
int i;
@ -243,7 +262,7 @@ IDE_Identify(IDE *ide, int drive)
else
driveCode = 0xB0;
ide_write_reg8(ide, 0, IDE_REG_DRIVE, driveCode);
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
status = IDEWaitForBusy(ide);
if ((status & IDE_STATUS_ERR) != 0) {
@ -277,28 +296,32 @@ IDE_Identify(IDE *ide, int drive)
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
char model[41];
char serial[21];
memcpy(&model[0], &ident.model[0], 40);
memcpy(&model[0], &ident.atap_model[0], 40);
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';
IDE_SwapAndTruncateString(&serial[0], 20);
//IDE_SwapAndTruncateString(&serial[0], 20);
kprintf("Drive %d Model: %s Serial: %s\n", drive, model, serial);
kprintf("Drive %d %lu Sectors (%llu MBs)\n",
drive, ident.lbaSectors, ident.lbaSectors / 2048ULL);
Log(ide, "Drive %d Model: \"%s\" Capabilities: 0x%x\n", drive, model, ident.atap_capabilities1);
// XXX: check capabilities
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].drive = drive;
primaryDrives[drive].lba48 = (ident.lbaSectors > (1 << 24));
primaryDrives[drive].size = ident.lbaSectors;
primaryDrives[drive].lba48 = (ident.atap_capacity > (1 << 24));
primaryDrives[drive].size = ident.atap_capacity;
// Register Disk
Disk *disk = PAlloc_AllocPage();
@ -310,231 +333,232 @@ IDE_Identify(IDE *ide, int drive)
disk->ctrlNo = 0;
disk->diskNo = drive;
disk->sectorSize = IDE_SECTOR_SIZE;
disk->sectorCount = ident.lbaSectors;
disk->diskSize = IDE_SECTOR_SIZE * ident.lbaSectors;
// disk->read = IDE_Read;
// disk->write = IDE_Write;
// disk->flush = IDE_Flush;
disk->sectorCount = ident.atap_capacity;
disk->diskSize = IDE_SECTOR_SIZE * ident.atap_capacity;
disk->read = IDE_Read;
disk->write = IDE_Write;
disk->flush = IDE_Flush;
// Disk_AddDisk(disk);
Disk_AddDisk(disk);
}
// int
// IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
// {
// int i;
// int status;
// IDEDrive *idedrive;
int
IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
{
unsigned int i;
int status;
IDEDrive *idedrive;
// idedrive = disk->handle;
idedrive = disk->handle;
// for (i = 0; i < sga->len; i++) {
// status = IDE_ReadOne(idedrive,
// buf,
// sga->entries[i].offset / 512,
// sga->entries[i].length / 512);
// buf += sga->entries[i].length;
// if (status < 0)
// return status;
// }
for (i = 0; i < sga->len; i++) {
status = IDE_ReadOne(idedrive,
buf,
sga->entries[i].offset / 512,
sga->entries[i].length / 512);
buf += sga->entries[i].length;
if (status < 0)
return status;
}
// return 0;
// }
return 0;
}
// int
// IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
// {
// int i;
// int status;
// IDEDrive *idedrive;
int
IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
{
unsigned int i;
int status;
IDEDrive *idedrive;
// idedrive = disk->handle;
idedrive = disk->handle;
// for (i = 0; i < sga->len; i++) {
// status = IDE_WriteOne(idedrive,
// buf,
// sga->entries[i].offset / 512,
// sga->entries[i].length / 512);
// buf += sga->entries[i].length;
// if (status < 0)
// return status;
// }
for (i = 0; i < sga->len; i++) {
status = IDE_WriteOne(idedrive,
buf,
sga->entries[i].offset / 512,
sga->entries[i].length / 512);
buf += sga->entries[i].length;
if (status < 0)
return status;
}
// return 0;
// }
return 0;
}
// int
// IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
// {
// uint8_t driveCode;
// IDE *ide;
// IDEDrive *idedrive;
int
IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB cb, void *arg)
{
uint8_t driveCode;
IDE *ide;
IDEDrive *idedrive;
// idedrive = disk->handle;
// ide = idedrive->ide;
idedrive = disk->handle;
ide = idedrive->ide;
// if (idedrive->drive == 0)
// driveCode = 0xA0;
// else
// driveCode = 0xB0;
if (idedrive->drive == 0)
driveCode = 0xA0;
else
driveCode = 0xB0;
// Spinlock_Lock(&ide->lock);
// outb(ide->base + IDE_DRIVE, driveCode);
// outb(ide->base + IDE_COMMAND, IDE_CMD_FLUSH);
Spinlock_Lock(&ide->lock);
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_FLUSH);
// IDEWaitForBusy(ide, false);
// Spinlock_Unlock(&ide->lock);
IDEWaitForBusy(ide);
Spinlock_Unlock(&ide->lock);
// return 0;
// }
return 0;
}
// int
// IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
// {
// bool lba48 = false;
// uint8_t driveCode;
// uint8_t status;
// IDE *ide = drive->ide;
int
IDE_ReadOne(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);
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)
// driveCode = lba48 ? 0x40 : 0xE0;
// else
// driveCode = lba48 ? 0x50 : 0xF0;
if (drive->drive == 0)
driveCode = lba48 ? 0x40 : 0xE0;
else
driveCode = lba48 ? 0x50 : 0xF0;
// ASSERT(len < 0x10000);
ASSERT(len < 0x10000);
// Spinlock_Lock(&ide->lock);
// if (driveCode != ide->lastDriveCode) {
// outb(ide->base + IDE_DRIVE, driveCode);
Spinlock_Lock(&ide->lock);
if (driveCode != ide->lastDriveCode) {
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
// // Need to wait for select to complete
// status = IDEWaitForBusy(ide, true);
// if ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error selecting drive %d\n", drive->drive);
// return -1;
// }
// ide->lastDriveCode = driveCode;
// }
// Need to wait for select to complete
status = IDEWaitForBusy(ide);
if ((status & IDE_STATUS_ERR) != 0) {
Spinlock_Unlock(&ide->lock);
Log(ide, "Error selecting drive %d\n", drive->drive);
return EIO;
}
ide->lastDriveCode = driveCode;
}
// if (lba48) {
// outb(ide->base + IDE_SECTORCOUNT, len >> 8);
// outb(ide->base + IDE_LBALOW, off >> 24);
// outb(ide->base + IDE_LBAMID, off >> 32);
// outb(ide->base + IDE_LBAHIGH, 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_SECCOUNT1, len >> 8);
ide_write_reg8(ide, 0, IDE_REG_LBA3, off >> 24);
ide_write_reg8(ide, 0, IDE_REG_LBA4, off >> 32);
ide_write_reg8(ide, 0, IDE_REG_LBA5, off >> 40);
}
// if (lba48)
// outb(ide->base + IDE_COMMAND, IDE_CMD_READ_EXT);
// else
// outb(ide->base + IDE_COMMAND, IDE_CMD_READ);
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 ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error trying read from drive %d\n", drive->drive);
// return -1;
// }
if (lba48)
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_READ_EXT);
else
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_READ);
// int sectors;
// for (sectors = 0; sectors < len; sectors++)
// {
// uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
// insw(ide->base + IDE_DATAPORT, b, 256);
status = IDEWaitForBusy(ide);
if ((status & IDE_STATUS_ERR) != 0) {
Spinlock_Unlock(&ide->lock);
Log(ide, "Error trying read from drive %d\n", drive->drive);
return EIO;
}
// status = IDEWaitForBusy(ide, true);
// if ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error reading from drive %d\n", drive->drive);
// return -1;
// }
// }
// Spinlock_Unlock(&ide->lock);
unsigned int sectors;
for (sectors = 0; sectors < len; sectors++)
{
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
ide_read_buf16(ide, 0, b, IDE_SECTOR_SIZE / sizeof(uint16_t));
// 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
// 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;
return 0;
}
// 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)
// driveCode = lba48 ? 0x40 : 0xE0;
// else
// driveCode = lba48 ? 0x50 : 0xF0;
ASSERT(drive->drive == 0 || drive->drive == 1);
// ASSERT(len < 0x10000);
if (drive->drive == 0)
driveCode = lba48 ? 0x40 : 0xE0;
else
driveCode = lba48 ? 0x50 : 0xF0;
// Spinlock_Lock(&ide->lock);
// if (driveCode != ide->lastDriveCode) {
// outb(ide->base + IDE_DRIVE, driveCode);
ASSERT(len < 0x10000);
// // Need to wait for select to complete
// status = IDEWaitForBusy(ide, true);
// if ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error selecting drive %d\n", drive->drive);
// return -1;
// }
// ide->lastDriveCode = driveCode;
// }
Spinlock_Lock(&ide->lock);
if (driveCode != ide->lastDriveCode) {
ide_write_reg8(ide, 0, IDE_REG_HDDEVSEL, driveCode);
// if (lba48) {
// outb(ide->base + IDE_SECTORCOUNT, len >> 8);
// outb(ide->base + IDE_LBALOW, off >> 24);
// outb(ide->base + IDE_LBAMID, off >> 32);
// outb(ide->base + IDE_LBAHIGH, 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);
// Need to wait for select to complete
status = IDEWaitForBusy(ide);
if ((status & IDE_STATUS_ERR) != 0) {
Spinlock_Unlock(&ide->lock);
Log(ide, "Error selecting drive %d\n", drive->drive);
return EIO;
}
ide->lastDriveCode = driveCode;
}
// if (lba48)
// outb(ide->base + IDE_COMMAND, IDE_CMD_WRITE_EXT);
// else
// outb(ide->base + IDE_COMMAND, IDE_CMD_WRITE);
if (lba48) {
ide_write_reg8(ide, 0, IDE_REG_SECCOUNT1, len >> 8);
ide_write_reg8(ide, 0, IDE_REG_LBA3, off >> 24);
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 ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error trying read from drive %d\n", drive->drive);
// return -1;
// }
if (lba48)
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_WRITE_EXT);
else
ide_write_reg8(ide, 0, IDE_REG_COMMAND, IDE_CMD_WRITE);
// int sectors;
// for (sectors = 0; sectors < len; sectors++)
// {
// uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
// outsw(ide->base + IDE_DATAPORT, b, 256);
status = IDEWaitForBusy(ide);
if ((status & IDE_STATUS_ERR) != 0) {
Spinlock_Unlock(&ide->lock);
Log(ide, "Error trying read from drive %d\n", drive->drive);
return EIO;
}
// status = IDEWaitForBusy(ide, true);
// if ((status & IDE_STATUS_ERR) != 0) {
// Spinlock_Unlock(&ide->lock);
// Log(ide, "Error reading from drive %d\n", drive->drive);
// return -1;
// }
// }
// Spinlock_Unlock(&ide->lock);
unsigned int sectors;
for (sectors = 0; sectors < len; sectors++)
{
uint8_t *b = buf + sectors * IDE_SECTOR_SIZE;
ide_write_buf16(ide, 0, b, IDE_SECTOR_SIZE / sizeof(uint16_t));
// // 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;
}

View File

@ -42,12 +42,12 @@ NO_RETURN void Debug_Assert(const char *fmt, ...);
#define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__)
// Normal Logging
#define Log(_module, _format, ...) \
if (SYSCTL_GETINT(log_##_module) >= 1) { \
if (SYSCTL_GETINT(log_##_module) >= 1 || 1) { \
kprintf(#_module ": " _format, ##__VA_ARGS__); \
}
// Debug Logging
#define DLOG(_module, _format, ...) \
if (SYSCTL_GETINT(log_##_module) >= 5) { \
if (SYSCTL_GETINT(log_##_module) >= 5 || 1) { \
kprintf(#_module ": " _format, ##__VA_ARGS__); \
}
// Verbose Logging

View File

@ -29,7 +29,8 @@
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_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

View File

@ -40,7 +40,7 @@ void
BufCache_Init()
{
int i;
Log(bufcache, "Initializing ...\n");
Spinlock_Init(&cacheLock, "BufCache Lock", SPINLOCK_TYPE_NORMAL);
diskBuf = XMem_New();
@ -78,6 +78,8 @@ BufCache_Init()
cacheHit = 0;
cacheMiss = 0;
cacheAlloc = 0;
Log(bufcache, "Initialized!\n");
}
/**

View File

@ -36,7 +36,7 @@ int
VFS_MountRoot(Disk *rootDisk)
{
int status;
Log(vfs, "Mounting root...\n");
Spinlock_Init(&vfsLock, "VFS Lock", SPINLOCK_TYPE_NORMAL);
Slab_Init(&vfsSlab, "VFS Slab", sizeof(VFS), 16);
@ -49,7 +49,7 @@ VFS_MountRoot(Disk *rootDisk)
status = rootFS->op->getroot(rootFS, &rootNode);
if (status < 0)
Panic("Failed to get root VNode\n");
Log(vfs, "Root mounted!\n");
return 0;
}