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 // 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
*/ */

View File

@ -5,30 +5,242 @@
#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);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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");
} }
/** /**

View File

@ -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;
} }