Fix IDE on new qemu, virtualbox
This commit is contained in:
parent
4e36047f2c
commit
50ea1462c3
2
Makefile
2
Makefile
@ -69,6 +69,8 @@ term: system
|
||||
${EMU} ${EMUARGS} -append "vid=qemu single hdd"
|
||||
term-kvm: system
|
||||
${EMU} ${EMUARGS} ${EMUKVM} -append "vid=qemu single hdd"
|
||||
debug: system
|
||||
${EMU} ${EMUARGS} -append "logtoserial=0 vid=qemu hdd"
|
||||
run-config: system
|
||||
util/config-parser | xargs ${EMU}
|
||||
|
||||
|
@ -17,13 +17,17 @@ void ide_detect() {
|
||||
|
||||
}
|
||||
|
||||
void ata_io_wait(uint16_t bus) {
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
}
|
||||
|
||||
int ata_wait(uint16_t bus, int advanced) {
|
||||
uint8_t status = 0;
|
||||
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
inportb(bus + ATA_REG_ALTSTATUS);
|
||||
ata_io_wait(bus);
|
||||
|
||||
while ((status = inportb(bus + ATA_REG_STATUS)) & ATA_SR_BSY);
|
||||
|
||||
@ -38,7 +42,7 @@ int ata_wait(uint16_t bus, int advanced) {
|
||||
}
|
||||
|
||||
void ata_select(uint16_t bus) {
|
||||
outportb(bus + ATA_REG_HDDEVSEL, 0xB0);
|
||||
outportb(bus + ATA_REG_HDDEVSEL, 0xA0);
|
||||
}
|
||||
|
||||
void ata_wait_ready(uint16_t bus) {
|
||||
@ -46,23 +50,62 @@ void ata_wait_ready(uint16_t bus) {
|
||||
}
|
||||
|
||||
void ide_init(uint16_t bus) {
|
||||
|
||||
debug_print(NOTICE, "initializing IDE device on bus %d", bus);
|
||||
|
||||
outportb(bus + 1, 1);
|
||||
outportb(bus + 0x306, 0);
|
||||
|
||||
ata_select(bus);
|
||||
ata_wait(bus, 1);
|
||||
ata_io_wait(bus);
|
||||
|
||||
outportb(bus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
|
||||
ata_io_wait(bus);
|
||||
|
||||
int status = inportb(bus + ATA_REG_COMMAND);
|
||||
debug_print(INFO, "status = %x", status);
|
||||
|
||||
ata_wait_ready(bus);
|
||||
|
||||
ata_identify_t device;
|
||||
uint16_t * buf = (uint16_t *)&device;
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
buf[i] = inports(bus);
|
||||
}
|
||||
|
||||
uint8_t * ptr = (uint8_t *)&device.model;
|
||||
for (int i = 0; i < 39; i+=2) {
|
||||
uint8_t tmp = ptr[i+1];
|
||||
ptr[i+1] = ptr[i];
|
||||
ptr[i] = tmp;
|
||||
}
|
||||
|
||||
debug_print(NOTICE, "ata device %s", device.model);
|
||||
debug_print(NOTICE, "sectors_48 = %d", (uint32_t)device.sectors_48);
|
||||
debug_print(NOTICE, "sectors_28 = %d", device.sectors_28);
|
||||
|
||||
outportb(bus + ATA_REG_CONTROL, 0x02);
|
||||
}
|
||||
|
||||
void ide_read_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf) {
|
||||
outportb(bus + ATA_REG_CONTROL, 0x02);
|
||||
|
||||
ata_wait_ready(bus);
|
||||
|
||||
outportb(bus + ATA_REG_HDDEVSEL, 0xe0 | slave << 4 |
|
||||
(lba & 0x0f000000) >> 24);
|
||||
ata_wait(bus, 0);
|
||||
outportb(bus + ATA_REG_FEATURES, 0x00);
|
||||
outportb(bus + ATA_REG_SECCOUNT0, 1);
|
||||
outportb(bus + ATA_REG_LBA0, (lba & 0x000000ff) >> 0);
|
||||
outportb(bus + ATA_REG_LBA1, (lba & 0x0000ff00) >> 8);
|
||||
outportb(bus + ATA_REG_LBA2, (lba & 0x00ff0000) >> 16);
|
||||
outportb(bus + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
|
||||
|
||||
if (ata_wait(bus, 1)) {
|
||||
debug_print(WARNING, "Error during ATA read");
|
||||
}
|
||||
|
||||
int size = 256;
|
||||
inportsm(bus,buf,size);
|
||||
ata_wait(bus, 0);
|
||||
@ -70,6 +113,7 @@ void ide_read_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf) {
|
||||
|
||||
void ide_write_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf) {
|
||||
outportb(bus + ATA_REG_CONTROL, 0x02);
|
||||
|
||||
ata_wait_ready(bus);
|
||||
|
||||
outportb(bus + ATA_REG_HDDEVSEL, 0xe0 | slave << 4 |
|
||||
@ -81,7 +125,7 @@ void ide_write_sector(uint16_t bus, uint8_t slave, uint32_t lba, uint8_t * buf)
|
||||
outportb(bus + ATA_REG_LBA1, (lba & 0x0000ff00) >> 8);
|
||||
outportb(bus + ATA_REG_LBA2, (lba & 0x00ff0000) >> 16);
|
||||
outportb(bus + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
|
||||
ata_wait(bus, 1);
|
||||
ata_wait(bus, 0);
|
||||
int size = 256;
|
||||
outportsm(bus,buf,size);
|
||||
outportb(bus + 0x07, ATA_CMD_CACHE_FLUSH);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
#include <pipe.h>
|
||||
#include <logging.h>
|
||||
|
||||
#define DEBUG_PIPES 0
|
||||
|
||||
|
@ -113,6 +113,26 @@ typedef struct {
|
||||
uint32_t sector_count;
|
||||
} partition_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t flags;
|
||||
uint16_t unused1[9];
|
||||
char serial[20];
|
||||
uint16_t unused2[3];
|
||||
char firmware[8];
|
||||
char model[40];
|
||||
uint16_t sectors_per_int;
|
||||
uint16_t unused3;
|
||||
uint16_t capabilities[2];
|
||||
uint16_t unused4[2];
|
||||
uint16_t valid_ext_data;
|
||||
uint16_t unused5[5];
|
||||
uint16_t size_of_rw_mult;
|
||||
uint32_t sectors_28;
|
||||
uint16_t unused6[38];
|
||||
uint64_t sectors_48;
|
||||
uint16_t unused7[152];
|
||||
} __attribute__((packed)) ata_identify_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t boostrap[446];
|
||||
partition_t partitions[4];
|
||||
|
@ -78,6 +78,7 @@ parse_args(
|
||||
debug_print(WARNING, "Unrecognized video adapter: %s", argp[1]);
|
||||
}
|
||||
} else if (!strcmp(argp[0],"hdd")) {
|
||||
ide_init(0x1F0);
|
||||
if (argc > 1) {
|
||||
debug_print(INFO, "Scanning disk...");
|
||||
if (read_partition_map(0)) {
|
||||
|
@ -519,6 +519,16 @@ static int system_function(int fn, char ** args) {
|
||||
kprintf("Setting output to file object in process %d's fd=%d!\n", getpid(), (int)args);
|
||||
kprint_to_file = current_process->fds->entries[(int)args];
|
||||
break;
|
||||
case 5:
|
||||
debug_print(INFO, "replacing process %d's file descriptors with null devices", getpid());
|
||||
fs_node_t * nulldev = null_device_create();
|
||||
while (current_process->fds->length < 3) {
|
||||
process_append_fd((process_t *)current_process, nulldev);
|
||||
}
|
||||
current_process->fds->entries[0] = nulldev;
|
||||
current_process->fds->entries[1] = nulldev;
|
||||
current_process->fds->entries[2] = nulldev;
|
||||
break;
|
||||
default:
|
||||
kprintf("Bad system function %d\n", fn);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user