All pastes #1815148 Raw Edit

richard

public text v1 · immutable
#1815148 ·published 2010-02-28 01:25 UTC
rendered paste body
Index: pci.cpp===================================================================--- pci.cpp	(revision 319)+++ pci.cpp	(working copy)@@ -37,6 +37,7 @@ 		case 0xffff: return "NONE"; 		case 0x1013: return "Cirrus Logic"; 		case 0x10ec: return "Realtek Semiconductor";+		case 0x80ee: return "VirtualBox"; 		default: return vendor_unknown; 	} }Index: Makefile===================================================================--- Makefile	(revision 315)+++ Makefile	(working copy)@@ -10,7 +10,7 @@  all: barebones tty2.o FS_MODULES = fs/ramdisk.o fs/cpiofs.o  fs/devfs.o fs/fs.o fs/sink.o-MODULES= loader.o heap.o task.o newpipe.o kbd.o sched.o start.o exception.o lowlevel.o  gdt.o  isr.o idt.o interrupts.o  timer.o syscall.o  std_streams.o multiboot.o vm2.o elf.o tty2.o terminal.o list.o kernelpokes.o $(FS_MODULES)+MODULES= loader.o heap.o task.o newpipe.o kbd.o sched.o start.o exception.o lowlevel.o  gdt.o  isr.o idt.o interrupts.o  timer.o syscall.o  std_streams.o ata.o ata2.o multiboot.o vm2.o elf.o tty2.o terminal.o list.o kernelpokes.o $(FS_MODULES)  barebones.img: barebones bootfloppy.img menu.cfg 	cp bootfloppy.img $@@@ -25,6 +25,8 @@ 	$(CXX) $(CXXFLAGS) -c $< %.o: %.asm 	$(ASM) $(ASMFLAGS) -l $<.lst $<+%.S: %.cpp+	$(CXX) $(CXXFLAGS) -S  $< .PHONY: clean wc: 	wc -l `find -name "*.asm"` `find -name "*.c"` `find -name "*.h"` `find -name "*.cpp"` `find -name "*.hpp"`Index: start.cpp===================================================================--- start.cpp	(revision 309)+++ start.cpp	(working copy)@@ -21,6 +21,7 @@ #include "std_streams.h"  #include "sched.h" #include "heap.h"+#include "ata.h" // the virtual address of the console. #define VIDMEM ((unsigned short *)0xC00B8000) @@ -28,7 +29,7 @@ Console console(VIDMEM); Terminal con_inst(&console); Terminal* con(&con_inst);-+void ide_initialize(u32,u32,u32,u32,u32); // tasks we're going to create Task initial_task,idle_task; 	// stacks@@ -89,6 +90,8 @@ 	devfs.register_device("null",&dnull); 	devfs.register_device("zero",&dzero); }++ void _main(UNUSED multiboot_t* mbd,UNUSED unsigned int magic ){ 	MultiBoot mb(mbd); 	//physmem.set_kernel_usage(u32(&__end)-KERNEL_BASE_ADDRESS);@@ -160,7 +163,8 @@ 	con->printf("Starting initial task \"%s\"...\n\n",PROGRAM_NAME); 	parseElf(fstestfd,&initial_task,USER_MODE); 	scheduler.addTask(&initial_task);-+// ide_initialize(0x1F0, 0x3F4, 0x170, 0x374, 0x000);+	ide_initialize(0,0,0,0,0); // tss_flush(); // con->putval("Sizeof(Task):",sizeof(Task)); // 	con_inst.print("Enabling interrupts...\n");Index: vm2.cpp===================================================================--- vm2.cpp	(revision 322)+++ vm2.cpp	(working copy)@@ -283,9 +283,10 @@ 	//pt[virt&0xfff].set(phys,user,writable); 	invalidate_addr((void*)virt); }+#define PAGE_ALIGN(x) ((x)&0xFFFFE000) bool AddressSpace::verify_range(u32 start,u32 len,bool user,bool writable) {-	u32 curr=start;-	u32 end=start+len;+	u32 curr=PAGE_ALIGN(start);+	u32 end=PAGE_ALIGN(start+len); 	if(end<curr) return true; 	while(curr<=end) { 		directory_entry& dirent=get_dir_entry(curr);Index: rebuild===================================================================--- rebuild	(revision 216)+++ rebuild	(working copy)@@ -11,4 +11,5 @@ sync sync #bochs -f bochs.conf-qemu -fda bootfloppy.img+./run +#qemu -fda bootfloppy.imgIndex: terminal.h===================================================================--- terminal.h	(revision 278)+++ terminal.h	(working copy)@@ -21,4 +21,8 @@ 	Console*con; }; extern Terminal *con;+extern "C" void printk(const char* fmt,...);++// #define printk con->printf+ #endifIndex: ata2.asm===================================================================--- ata2.asm	(revision 0)+++ ata2.asm	(revision 0)@@ -0,0 +1,372 @@+; base port register+%define BASE_IO_PORT 0x1f0+%define BASE_CMD_PORT 0x3f4++%define ATA_SR_BSY     0x80+%define ATA_SR_DRDY    0x40+%define ATA_SR_DF      0x20+%define ATA_SR_DSC     0x10+%define ATA_SR_DRQ     0x08+%define ATA_SR_CORR    0x04+%define ATA_SR_IDX     0x02+%define ATA_SR_ERR     0x01+%define ATA_ER_BBK      0x80+%define ATA_ER_UNC      0x40+%define ATA_ER_MC       0x20+%define ATA_ER_IDNF     0x10+%define ATA_ER_MCR      0x08+%define ATA_ER_ABRT     0x04+%define ATA_ER_TK0NF    0x02+%define ATA_ER_AMNF     0x01++%define ATA_CMD_READ_PIO          0x20+%define ATA_CMD_READ_PIO_EXT      0x24+%define ATA_CMD_READ_DMA          0xC8+%define ATA_CMD_READ_DMA_EXT      0x25+%define ATA_CMD_WRITE_PIO         0x30+%define ATA_CMD_WRITE_PIO_EXT     0x34+%define ATA_CMD_WRITE_DMA         0xCA+%define ATA_CMD_WRITE_DMA_EXT     0x35+%define ATA_CMD_CACHE_FLUSH       0xE7+%define ATA_CMD_CACHE_FLUSH_EXT   0xEA+%define ATA_CMD_PACKET            0xA0+%define ATA_CMD_IDENTIFY_PACKET   0xA1+%define ATA_CMD_IDENTIFY          0xEC+%define ATA_MODE 0xe+;     *  Data Register: BAR0 + 0; // Read-Write+;     * Error Register: BAR0 + 1; // Read Only+;     * Features Register: BAR0 + 1; // Write Only+;     * SECCOUNT0: BAR0 + 2; // Read-Write+;     * LBA0: BAR0 + 3; // Read-Write+;     * LBA1: BAR0 + 4; // Read-Write+;     * LBA2: BAR0 + 5; // Read-Write+;     * HDDEVSEL: BAR0 + 6; // Read-Write, used to select a drive in the channel.+;     * Command Register: BAR0 + 7; // Write Only.+;     * Status Register: BAR0 + 7; // Read Only.+;     * Alternate Status Register: BAR1 + 2; // Read Only.+;     * Control Register: BAR1 + 2; // Write Only.+;     * DEVADDRESS: BAR1 + 2; // I don't know what is the benefit from this register.+%define ATA_REG_DATA       BASE_IO_PORT+0x00+%define ATA_REG_ERROR      BASE_IO_PORT+0x01+%define ATA_REG_FEATURES   BASE_IO_PORT+0x01+%define ATA_REG_SECCOUNT0  BASE_IO_PORT+0x02+%define ATA_REG_LBA0       BASE_IO_PORT+0x03+%define ATA_REG_LBA1       BASE_IO_PORT+0x04+%define ATA_REG_LBA2       BASE_IO_PORT+0x05+%define ATA_REG_HDDEVSEL   BASE_IO_PORT+0x06+%define ATA_REG_COMMAND    BASE_IO_PORT+0x07+%define ATA_REG_STATUS     BASE_IO_PORT+0x07+; %define ATA_REG_SECCOUNT1  BASE_IO_PORT+0x08+; %define ATA_REG_LBA3       BASE_IO_PORT+0x09+; %define ATA_REG_LBA4       BASE_IO_PORT+0x0A+; %define ATA_REG_LBA5       BASE_IO_PORT+0x0B+%define ATA_REG_CONTROL    BASE_CMD_PORT+0x02+%define ATA_REG_ALTSTATUS  BASE_CMD_PORT+0x02+; %define ATA_REG_DEVADDRESS BASE_CMD_PORT+0x02++%define high_io [ebx+4]+%define low_io [ebx]+cursor: dd 0xc00b8040+putch:+push ebx+and ax,0x00ff+or ax,0x7000+mov ebx,[cursor]+add bx,2+mov [ebx],ax+mov [cursor],ebx+pop ebx+ret+%macro GETSTATUS 0+xor eax,eax+; mov edx,high_io ; mov dx,ATA_REG_ALTSTATUS+; add dx,2+mov edx,[ebx]+add dx,7+in al,dx+%endmacro++%macro PRINTSTATUS 0+GETSTATUS+push eax+call printstatus+pop eax+%endmacro++wait_for_busy:+GETSTATUS++test ax,ATA_SR_BSY+jz .end+inc word [0xc00b8002]+jmp wait_for_busy+.end:+ret+wait_for_drq:+GETSTATUS+; push eax+; call printstatus+; pop eax++test ax,ATA_SR_DRQ++jnz .end+inc word [0xc00b8012]+jmp wait_for_drq+.end:+ret+wait_for_ready:+GETSTATUS+test ax,ATA_SR_DRDY+jnz .end+inc word [0xc00b8004]+jmp wait_for_ready+.end:+ret+; %macro GETADDRESS+global ata_issue_identify+global ata_read_buffer+global ata_28bit_operation+global ata_read_test+extern printstatus+; param 1, drive no.+; param 2, buffer+; param 3, low io port+; param 4, high io port+; return 1 if not present, 0 otherwise++ata_issue_identify:+push ebp+mov ebp,esp+push ebx+mov ebx,ebp+add ebx,16+; select drive+mov edx,[ebx]   ; mov dx,ATA_REG_HDDEVSEL+add edx, 6++mov eax, [ebp+8]+and al,1	; do the bit twiddling+shl al,4+or al,ATA_MODE+out dx,al+; PRINTSTATUS+GETSTATUS ; pause a bit+GETSTATUS+GETSTATUS+++call wait_for_busy+; wait for rdy+; PRINTSTATUS+; GETSTATUS+; test al,ATA_SR_ERR+; jz .noerror+; xor eax,eax+; ret+; .noerror:+GETSTATUS+test al,ATA_SR_DRDY+jnz .noerror2+xor eax,eax+pop ebx+pop ebp+ret+.noerror2:+; call wait_for_ready+; now issue the identify command.+mov ax, ATA_CMD_IDENTIFY+mov edx,low_io ; mov dx,ATA_REG_COMMAND+add dx,7+out dx,al+; wait a few ticks+GETSTATUS+GETSTATUS+GETSTATUS+GETSTATUS+++; wait for !bsy and drq+call wait_for_busy+call wait_for_drq++; param 1, buffer (fixed at 512b len)+; param 2, low io port+; param 3, high io port+++push dword [ebx+4]+push dword [ebx]+mov eax,[ebp+12]+push eax ; buffer ad.+call ata_read_buffer+add esp,12+; read into the buffer+; it's possible a string instruction is incorrect though... it works///+; mov edx,[ebx]	; data reg, no offset+; mov edi, [ebp+12]	; destination buf+; mov ecx,128 ; count (128 dwords = 512b)+; cld+; rep insd+; ;++pop ebx+pop ebp+ret+++; param 1, buffer (fixed at 512b len)+; param 2, low io port+; param 3, high io port+ata_read_buffer:+push ebx+mov ebx,esp+add ebx,12+push edi+GETSTATUS+test al,ATA_SR_BSY|ATA_SR_ERR+jnz .end+test al,ATA_SR_DRQ+jz .end+++; read into the buffer+; it's possible a string instruction is incorrect though... it works///+mov edx,[ebx]	; data reg, no offset+mov edi, [ebx-4]	; destination buf+mov ecx,128 ; count (128 dwords = 512b)+cld+rep insd+;++.end:+pop edi+pop ebx+ret+extern ide_buf+; param 1 low io+; param 2 high+ata_read_test:+push ebp+mov ebp,esp+push ebx+mov ebx,ebp+add ebx,8+push dword 0	; loop counter+push dword 0	; read it+push dword 1 ; sector+push dword [ebx+4] ; high io+push dword [ebx] ; low io+push dword ide_buf ; buffer+push dword 0	; drive number+.loop1:+mov [ide_buf],dword 0+mov eax,[esp+24]+and eax,0xf+shl eax,18+mov [esp+16],eax+inc word [0xc00b8024]++call ata_28bit_operation+call wait_for_busy+call wait_for_drq+GETSTATUS+test eax,ATA_SR_ERR+jz .noerror+PRINTSTATUS+.noerror:++push dword [ebx+4] ; high io+push dword [ebx] ; low io+push dword ide_buf ; buffer+call ata_read_buffer+add esp,12++mov al, [ide_buf]+call putch+mov al, [ide_buf+1]+call putch+mov al, [ide_buf+2]+call putch++; mov [0xc00b8040],eax+inc dword [esp+24]+mov eax,[esp+24]+cmp eax,1<<16+; jle .loop1+add esp,28+pop ebx+pop ebp++ret+; param 1, drive no.+; param 2, buffer+; param 3, low io port+; param 4, high io port+; param 5, sector number+; param 6, direction 1=write,0=read+; return 1 if not present, 0 otherwise++ata_28bit_operation:+push ebp+mov ebp,esp+push ebx+mov ebx,ebp+add ebx,16 ; param block+sub esp,4+mov eax,[ebx+8]+mov [esp],al ; lba_0+shr eax,8+mov [esp+1],al ; lba 1+shr eax,8+mov [esp+2],al ; lba 2+shr eax,8; eax=head address+and al,0xf ; should be unnecessary+mov [esp+3],al++call wait_for_busy+; PRINTSTATUS+; select drive+mov edx,[ebx]   ; mov dx,ATA_REG_HDDEVSEL+add edx, 6++mov eax, [ebp+8]+and al,1	; do the bit twiddling+shl al,4+or al,0xe0+or al,[esp+3]	; head count+out dx,al++mov edx,[ebx]+add dx,2+mov al,1+out dx,al	; sector count+inc dx+mov al,[esp]+out dx,al	; lba0+inc dx+mov al,[esp+1]+out dx,al	; lba1+inc dx+mov al,[esp+2]+out dx,al	; lba2++; mov eax,[ebx+8]+; test eax,eax+; jnz .writecmd+mov al,ATA_CMD_READ_PIO+; jmp .afterdecision+; .writecmd:+; mov al,ATA_CMD_WRITE_PIO+; .afterdecision:+mov edx,[ebx]+add dx,7 ; command register+out dx,al+; PRINTSTATUS+; prologue+add esp,4+pop ebx+pop ebp++ret+Index: bochs.conf===================================================================--- bochs.conf	(revision 315)+++ bochs.conf	(working copy)@@ -10,6 +10,7 @@ floppya: type=1_44, 1_44="bootfloppy.img", status=inserted # no floppyb ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14+ata0-master: type=disk, mode=flat, translation=auto, path="hdd", cylinders=0, heads=0, spt=0, biosdetect=auto, model="Generic 1234" ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 ata2: enabled=0 ata3: enabled=0Index: ata.h===================================================================--- ata.h	(revision 0)+++ ata.h	(revision 0)@@ -0,0 +1,14 @@++#ifndef ATA_HEADER+#define ATA_HEADER+#include "types.h"+extern "C" {+	u32 ata_issue_identify(u32 id,void *buf,u16 low,u16 high);+	u32 ata_read_buffer(void*,u16 low,u16 high);+	u32 ata_28bit_operation(u32 id,void*,u16 low,u16 high,u32 sector,u32 dir);+	void printstatus(u8 val);+	void ide_initialize(u32 BAR0, u32 BAR1, u32 BAR2, u32 BAR3,u32 BAR4);+	u32 ata_read_test(u16 low,u16 high);+}++#endifIndex: interrupts.cpp===================================================================--- interrupts.cpp	(revision 315)+++ interrupts.cpp	(working copy)@@ -32,7 +32,7 @@ 	if(code<32) { 		PANIC("Unhandled exception (and it wasn't done by the exceptionhandler)\n"); 	} else if(regs->int_no<48) {-		return;+// 		return; 		code-=32; 		con->printf("Unhandled IRQ (%d) - %s\n",code,IrqTargets[code]); 	} else {Index: lowlevel.asm===================================================================--- lowlevel.asm	(revision 290)+++ lowlevel.asm	(working copy)@@ -102,3 +102,24 @@     pop ebx               ; Get the original value of EBX back.    ret++++   ; printk trampoline:+; this is a stub to let me call con->printf from C and asm.+; not going to stay with c++ so will write new code to call printk+; also, typing con->printf is cumbersome. Once i figure out how to+;do naked functions in GCC I'll move it into a header. atm google+; doesn't turn up anything.+   global printk+   extern con+   extern _ZN8Terminal6printfEPKcz+   ; very much non-reentrant+   printktemp: dd 0+printk:+	pop dword [printktemp]+	push dword [con]+	call _ZN8Terminal6printfEPKcz+	pop dword [con]+	push dword [printktemp]+	retIndex: lowlevel.h===================================================================--- lowlevel.h	(revision 319)+++ lowlevel.h	(working copy)@@ -42,6 +42,16 @@ 	//asm volatile ("XCHG %BX, %BX");  }+#define insl(port, buf, nr) \+__asm__ ("cld;rep;insl\n\t"    \+::"d"(port), "D"(buf), "c"(nr))++#define outsl(buf, nr, port) \+__asm__ ("cld;rep;outsl\n\t"    \+::"d"(port), "S" (buf), "c" (nr))+inline void insw(u16 port,int count,u32 dest) {+      asm("rep insw" : : "c"(count), "d"(port), "D"(dest)); // Receive Data.+} inline void outb(u16 port, u8 value) {     asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));Index: ata.cpp===================================================================--- ata.cpp	(revision 0)+++ ata.cpp	(revision 0)@@ -0,0 +1,492 @@+#define ATA_SR_BSY     0x80+#define ATA_SR_DRDY    0x40+#define ATA_SR_DF      0x20+#define ATA_SR_DSC     0x10+#define ATA_SR_DRQ     0x08+#define ATA_SR_CORR    0x04+#define ATA_SR_IDX     0x02+#define ATA_SR_ERR     0x01+#define ATA_ER_BBK      0x80+#define ATA_ER_UNC      0x40+#define ATA_ER_MC       0x20+#define ATA_ER_IDNF     0x10+#define ATA_ER_MCR      0x08+#define ATA_ER_ABRT     0x04+#define ATA_ER_TK0NF    0x02+#define ATA_ER_AMNF     0x01++#define ATA_CMD_READ_PIO          0x20+#define ATA_CMD_READ_PIO_EXT      0x24+#define ATA_CMD_READ_DMA          0xC8+#define ATA_CMD_READ_DMA_EXT      0x25+#define ATA_CMD_WRITE_PIO         0x30+#define ATA_CMD_WRITE_PIO_EXT     0x34+#define ATA_CMD_WRITE_DMA         0xCA+#define ATA_CMD_WRITE_DMA_EXT     0x35+#define ATA_CMD_CACHE_FLUSH       0xE7+#define ATA_CMD_CACHE_FLUSH_EXT   0xEA+#define ATA_CMD_PACKET            0xA0+#define ATA_CMD_IDENTIFY_PACKET   0xA1+#define ATA_CMD_IDENTIFY          0xEC++#define      ATAPI_CMD_READ       0xA8+#define      ATAPI_CMD_EJECT      0x1B++#define ATA_IDENT_DEVICETYPE   0+#define ATA_IDENT_CYLINDERS    2+#define ATA_IDENT_HEADS        6+#define ATA_IDENT_SECTORS      12+#define ATA_IDENT_SERIAL       20+#define ATA_IDENT_MODEL        54+#define ATA_IDENT_CAPABILITIES 98+#define ATA_IDENT_FIELDVALID   106+#define ATA_IDENT_MAX_LBA      120+#define ATA_IDENT_COMMANDSETS  164+#define ATA_IDENT_MAX_LBA_EXT  200++#define IDE_ATA        0x00+#define IDE_ATAPI      0x01++#define ATA_MASTER     0x00+#define ATA_SLAVE      0x01++#define ATA_REG_DATA       0x00+#define ATA_REG_ERROR      0x01+#define ATA_REG_FEATURES   0x01+#define ATA_REG_SECCOUNT0  0x02+#define ATA_REG_LBA0       0x03+#define ATA_REG_LBA1       0x04+#define ATA_REG_LBA2       0x05+#define ATA_REG_HDDEVSEL   0x06+#define ATA_REG_COMMAND    0x07+#define ATA_REG_STATUS     0x07+#define ATA_REG_SECCOUNT1  0x08+#define ATA_REG_LBA3       0x09+#define ATA_REG_LBA4       0x0A+#define ATA_REG_LBA5       0x0B+#define ATA_REG_CONTROL    0x0C+#define ATA_REG_ALTSTATUS  0x0C+#define ATA_REG_DEVADDRESS 0x0D++// Channels:+#define      ATA_PRIMARY      0x00+#define      ATA_SECONDARY    0x01++// Directions:+#define      ATA_READ      0x00+#define      ATA_WRITE     0x01+#include "terminal.h"+#include "lowlevel.h"+#include "ata.h"++++// inline void insl(u16 port,void* dest,int count) {+//       asm("rep insl" : : "c"(count), "d"(port), "D"(dest)); // Receive Data.+// }+inline void io_delay(int n=4) {+	for(int i=0;i<n*50;++i)+		inb(0);+}+struct IDEChannelRegisters {+   unsigned short base;  // I/O Base.+   unsigned short ctrl;  // Control Base+   unsigned short bmide; // Bus Master IDE+   unsigned char  nIEN;  // nIEN (No Interrupt);+} channels[2];+++unsigned char ide_buf[2048] = {0};+unsigned static char ide_irq_invoked = 0;+UNUSED unsigned static char atapi_packet[12] = {0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};++struct ide_device {+   unsigned char  reserved;    // 0 (Empty) or 1 (This Drive really exists).+   unsigned char  channel;     // 0 (Primary Channel) or 1 (Secondary Channel).+   unsigned char  drive;       // 0 (Master Drive) or 1 (Slave Drive).+   unsigned short type;        // 0: ATA, 1:ATAPI.+   unsigned short signature;   // Drive Signature+   unsigned short capabilities;// Features.+   unsigned int   commandSets; // Command Sets Supported.+   unsigned int   size;        // Size in Sectors.+   unsigned char  model[41];   // Model in string.+} ide_devices[4];+unsigned char ide_read(unsigned char channel, unsigned char reg);+void ide_write(unsigned char channel, unsigned char reg, unsigned char data);+void ide_read_buffer(unsigned char channel, unsigned char reg, void* buffer,unsigned int quads);+// read an IDE register+unsigned char ide_read(unsigned char channel, unsigned char reg) {+   unsigned char result=0;+//    printk("Reading ide channel: %X reg %X\n",channel,reg);+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);+   if (reg < 0x08)+      result = inb(channels[channel].base + reg - 0x00);+   else if (reg < 0x0C)+      result = inb(channels[channel].base  + reg - 0x06);+   else if (reg < 0x0E)+      result = inb(channels[channel].ctrl  + reg - 0x0A);+   else if (reg < 0x16)+      result = inb(channels[channel].bmide + reg - 0x0E);+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);+   return result;+}++void ide_write(unsigned char channel, unsigned char reg, unsigned char data) {+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);+   if (reg < 0x08)+      outb(data, channels[channel].base  + reg - 0x00);+   else if (reg < 0x0C)+      outb(data, channels[channel].base  + reg - 0x06);+   else if (reg < 0x0E)+      outb(data, channels[channel].ctrl  + reg - 0x0A);+   else if (reg < 0x16)+      outb(data, channels[channel].bmide + reg - 0x0E);+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);+}++void printstatus(u8 val) {+	if(val&ATA_SR_BSY)+		con->print("BSY ");+	if(val&ATA_SR_DRDY)+		con->print("DRDY ");+	if(val&ATA_SR_DF)+		con->print("DF ");+	if(val&ATA_SR_DSC)+		con->print("DSC ");+	if(val&ATA_SR_DRQ)+		con->print("DRQ ");+	if(val&ATA_SR_CORR)+		con->print("CORR ");+	if(val&ATA_SR_IDX)+		con->print("IDX ");+	if(val&ATA_SR_ERR)+		con->print("ERR ");+ 	con->print("\n");+}+void ide_read_buffer(unsigned char channel, unsigned char reg, void* buffer,unsigned int quads) {+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);+   asm("pushw %es; movw %ds, %ax; movw %ax, %es");+   if (reg < 0x08)+//      ide_read_buffer(chan, ATA_REG_DATA, ide_buf, 128);++      insl(channels[channel].base  + reg - 0x00, buffer, quads);+   else if (reg < 0x0C)+      insl(channels[channel].base  + reg - 0x06, buffer, quads);+   else if (reg < 0x0E)+      insl(channels[channel].ctrl  + reg - 0x0A, buffer, quads);+   else if (reg < 0x16)+      insl(channels[channel].bmide + reg - 0x0E, buffer, quads);+   asm("popw %es;");+   if (reg > 0x07 && reg < 0x0C)+      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);+}++unsigned char ide_print_error(unsigned int drive, unsigned char err) {+   if (err == 0)+      return err;++   printk("IDE:");+   if (err == 1) {printk("- Device Fault\n     "); err = 19;}+   else if (err == 2) {+      unsigned char st = ide_read(ide_devices[drive].channel, ATA_REG_ERROR);+      if (st & ATA_ER_AMNF)   {printk("- No Address Mark Found\n     ");   err = 7;}+      if (st & ATA_ER_TK0NF)   {printk("- No Media or Media Error\n     ");   err = 3;}+      if (st & ATA_ER_ABRT)   {printk("- Command Aborted\n     ");      err = 20;}+      if (st & ATA_ER_MCR)   {printk("- No Media or Media Error\n     ");   err = 3;}+      if (st & ATA_ER_IDNF)   {printk("- ID mark not Found\n     ");      err = 21;}+      if (st & ATA_ER_MC)   {printk("- No Media or Media Error\n     ");   err = 3;}+      if (st & ATA_ER_UNC)   {printk("- Uncorrectable Data Error\n     ");   err = 22;}+      if (st & ATA_ER_BBK)   {printk("- Bad Sectors\n     ");       err = 13;}+   } else  if (err == 3)           {printk("- Reads Nothing\n     "); err = 23;}+     else  if (err == 4)  {printk("- Write Protected\n     "); err = 8;}+   printk("- [%s %s] %s\n",+      (const char *[]){"Primary", "Secondary"}[ide_devices[drive].channel], // Use the channel as an index into the array+      (const char *[]){"Master", "Slave"}[ide_devices[drive].drive], // Same as above, using the drive+      ide_devices[drive].model);++   return err;+}+void waitbusy(int i) {+	 for(;;) {+		u8 status = ide_read(i, ATA_REG_ALTSTATUS);+		if (!(status & ATA_SR_BSY))+ 			break; // Everything is right.+	 }+}+void print_disk_info(ide_device* d);+void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2, unsigned int BAR3,+unsigned int BAR4) {+   int k, count = 0;++ memset(ide_devices,0,sizeof(ide_devices));+ memset(channels,0,sizeof(channels));+   // 1- Detect I/O Ports which interface IDE Controller:+   channels[ATA_PRIMARY  ].base  = (BAR0 & 0xFFFFFFFC) + 0x1F0 * (!BAR0);+   printk("Channel 0 base: %X\n",channels[ATA_PRIMARY  ].base);++   channels[ATA_PRIMARY  ].ctrl  = (BAR1 & 0xFFFFFFFC) + 0x3F4 * (!BAR1);+   printk("Channel 0 ctl: %X\n",channels[ATA_PRIMARY  ].ctrl);+   channels[ATA_SECONDARY].base  = (BAR2 & 0xFFFFFFFC) + 0x170 * (!BAR2);+   channels[ATA_SECONDARY].ctrl  = (BAR3 & 0xFFFFFFFC) + 0x374 * (!BAR3);+   printk("Channel 1 ctl: %X\n",channels[ATA_SECONDARY].ctrl);+   channels[ATA_PRIMARY  ].bmide = (BAR4 & 0xFFFFFFFC) + 0; // Bus Master IDE+   channels[ATA_SECONDARY].bmide = (BAR4 & 0xFFFFFFFC) + 8; // Bus Master IDE+     ide_write(ATA_PRIMARY  , ATA_REG_CONTROL, 6);+	      ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 6);+    io_delay(5000);+//    ide_write(ATA_PRIMARY  , ATA_REG_CONTROL, 2);+    // 2- Disable IRQs:+   ide_write(ATA_PRIMARY  , ATA_REG_CONTROL, 2);+   ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);++   // 3- Detect ATA-ATAPI Devices:+   for (int i = 0; i < 2; i++)+      for (int j = 0; j < 2; j++) {+//   printk("HASHDHAHADSHDAH\n");++         UNUSED unsigned char err = 0, type = IDE_ATA, status;+         ide_devices[count].reserved = 0; // Assuming that no drive here.+status= ata_issue_identify(j,ide_buf,channels[i].base,channels[i].ctrl);+// printk("xxx\n");+/*         // (I) Select Drive:+          ide_write(i, ATA_REG_HDDEVSEL,0xa| (j << 4)); // Select Drive.++         io_delay(100); // Wait 1ms for drive select to work.+// 		  printk("status of %d,%d, after select: ",i,j);+//  printstatus(ide_read(i, ATA_REG_ALTSTATUS));+//  printk("\n");+// 		 waitbusy(i);++         // (II) Send ATA Identify Command:+//          ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);+//          io_delay(10); // This function should be implemented in your OS. which waits for 1 ms.+                   // it is based on System Timer Device Driver.+		          ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);+				  io_delay(100);+status=ide_read(i, ATA_REG_STATUS);+//  printk("status of %d,%d, after identify: ",i,j);+//  printstatus(status);+//  printk("\n");+         // (III) Polling:*/+         if (status == 0) {++			 continue; // If Status = 0, No Device.+		 }+ printk("Got drive on %d,%d, status: ",i,j);+ printstatus(ide_read(i, ATA_REG_ALTSTATUS));+//  printk("\n");++         // (IV) Probe for ATAPI Devices:+++// 				  io_delay(1000);+//  for(int t=0;t<50000;++t) {+/*+            status = ide_read(i, ATA_REG_STATUS);+            if ((status & ATA_SR_ERR)) {err = 1; break;} // If Err, Device is not ATA.+            if (!(status & ATA_SR_BSY))+ 				if(status & ATA_SR_DRQ)+					break; // Everything is right.+			io_delay(10);+// 					 con->print("Status: ");+//  printstatus(status);+//  printk("\n");+// 			printk("IDE status poll: %X\n",status);+// 			printstatus(status);+         }*/+// 		 if((status&ATA_SR_DRQ)==0) {+// 			 printk("No drive\n"); continue;+// 		 }+// 		 con->print("Status: ");+//  printstatus(status);+         // (V) Read Identification Space of the Device:+//          ide_read_buffer(i, ATA_REG_DATA, ide_buf, 128);++         // (VI) Read Device Parameters:+         ide_devices[count].reserved     = 1;+         ide_devices[count].type         = type;+         ide_devices[count].channel      = i;+         ide_devices[count].drive        = j;+         ide_devices[count].signature    = *((unsigned short *)(ide_buf + ATA_IDENT_DEVICETYPE));+         ide_devices[count].capabilities = *((unsigned short *)(ide_buf + ATA_IDENT_CAPABILITIES));+         ide_devices[count].commandSets  = *((unsigned int *)(ide_buf + ATA_IDENT_COMMANDSETS));++         // (VII) Get Size:+         if (ide_devices[count].commandSets & (1 << 26))+            // Device uses 48-Bit Addressing:+            ide_devices[count].size   = *((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA_EXT));+         else+            // Device uses CHS or 28-bit Addressing:+            ide_devices[count].size   = *((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA));++         // (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):+         for(k = 0; k < 40; k+=2) {+            ide_devices[count].model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];+			ide_devices[count].model[k+1] = ide_buf[ATA_IDENT_MODEL + k];+         }+		 u8* it=ide_devices[count].model+39;+// 		 printk("char=%d\n",ide_devices[count].model[38]);+		 while(*it==32) {+			 *it=0;+			 --it;+		 }+         ide_devices[count].model[40] = 0; // Terminate String.+// 		 printk("Got model: %s, %dKB\n",ide_devices[count].model,ide_devices[count].size/2);+//  PANIC("4");+         count++;+      }++   // 4- Print Summary:+   for (int i = 0; i < 4; i++)+      if (ide_devices[i].reserved == 1) {+	   print_disk_info(ide_devices+i);+//          printk(" Found %s Drive %dMB - %s\n",ide_devices[i].type==0?"ATA":"ATAPI",+//             ide_devices[i].size >>21,               /* Size */+//             ide_devices[i].model);+// 		 (ide_devices[i].capabilities & 0x200)?"LBA":"CHS"+      }+}+void print_disk_info(ide_device* d){+	         printk(" Found %s Drive %dMB - %s using %s %s\n",d->type==0?"ATA":"ATAPI",+            d->size >>11,               /* Size */+            d->model,+			(d->commandSets&(1<<26))?"48 bit":"28 bit",+		 (d->capabilities & 0x200)?"LBA":"CHS"+				   );+}++unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsigned int lba,+                             unsigned char numsects, unsigned short selector, unsigned int edi) {++   unsigned char lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */, dma /* 0: No DMA, 1: DMA */, cmd;+   unsigned char lba_io[6];+   unsigned int  channel      = ide_devices[drive].channel; // Read the Channel.+   unsigned int  slavebit      = ide_devices[drive].drive; // Read the Drive [Master/Slave]+   unsigned int  bus = channels[channel].base; // Bus Base, like 0x1F0 which is also data port.+   unsigned int  words      = 256; // Almost every ATA drive has a sector-size of 512-byte.+   unsigned short cyl, i;+   unsigned char head, sect, err=0;+   ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN = (ide_irq_invoked = 0x0) + 0x02);+      // (I) Select one from LBA28, LBA48 or CHS;+   if (lba >= 0x10000000) { // Sure Drive should support LBA in this case, or you are+                            // giving a wrong LBA.+      // LBA48:+      lba_mode  = 2;+      lba_io[0] = (lba & 0x000000FF) >> 0;+      lba_io[1] = (lba & 0x0000FF00) >> 8;+      lba_io[2] = (lba & 0x00FF0000) >> 16;+      lba_io[3] = (lba & 0xFF000000) >> 24;+      lba_io[4] = 0; // LBA28 is integer, so 32-bits are enough to access 2TB.+      lba_io[5] = 0; // LBA28 is integer, so 32-bits are enough to access 2TB.+      head      = 0; // Lower 4-bits of HDDEVSEL are not used here.+   } else if (ide_devices[drive].capabilities & 0x200)  { // Drive supports LBA?+      // LBA28:+      lba_mode  = 1;+      lba_io[0] = (lba & 0x00000FF) >> 0;+      lba_io[1] = (lba & 0x000FF00) >> 8;+      lba_io[2] = (lba & 0x0FF0000) >> 16;+      lba_io[3] = 0; // These Registers are not used here.+      lba_io[4] = 0; // These Registers are not used here.+      lba_io[5] = 0; // These Registers are not used here.+      head      = (lba & 0xF000000) >> 24;+   } else {+      // CHS:+      lba_mode  = 0;+      sect      = (lba % 63) + 1;+      cyl       = (lba + 1  - sect) / (16 * 63);+      lba_io[0] = sect;+      lba_io[1] = (cyl >> 0) & 0xFF;+      lba_io[2] = (cyl >> 8) & 0xFF;+      lba_io[3] = 0;+      lba_io[4] = 0;+      lba_io[5] = 0;+      head      = (lba + 1  - sect) % (16 * 63) / (63); // Head number is written to HDDEVSEL lower 4-bits.+   }+      // (II) See if drive supports DMA or not;+   dma = 0; // We don't support DMA+    // (III) Wait if the drive is busy;+   while (ide_read(channel, ATA_REG_ALTSTATUS) & ATA_SR_BSY)+      ; // Wait if busy.++      // (IV) Select Drive from the controller;+   if (lba_mode == 0)+      ide_write(channel, ATA_REG_HDDEVSEL, 0xA0 | (slavebit << 4) | head); // Drive & CHS.+   else+      ide_write(channel, ATA_REG_HDDEVSEL, 0xE0 | (slavebit << 4) | head); // Drive & LBA+      // (V) Write Parameters;+   if (lba_mode == 2) {+      ide_write(channel, ATA_REG_SECCOUNT1,   0);+      ide_write(channel, ATA_REG_LBA3,   lba_io[3]);+      ide_write(channel, ATA_REG_LBA4,   lba_io[4]);+      ide_write(channel, ATA_REG_LBA5,   lba_io[5]);+   }+   ide_write(channel, ATA_REG_SECCOUNT0,   numsects);+   ide_write(channel, ATA_REG_LBA0,   lba_io[0]);+   ide_write(channel, ATA_REG_LBA1,   lba_io[1]);+   ide_write(channel, ATA_REG_LBA2,   lba_io[2]);+      // (VI) Select the command and send it;+   // Routine that is followed:+   // If ( DMA & LBA48)   DO_DMA_EXT;+   // If ( DMA & LBA28)   DO_DMA_LBA;+   // If ( DMA & LBA28)   DO_DMA_CHS;+   // If (!DMA & LBA48)   DO_PIO_EXT;+   // If (!DMA & LBA28)   DO_PIO_LBA;+   // If (!DMA & !LBA#)   DO_PIO_CHS;++// There isn't a command for doing CHS with DMA.++   if (lba_mode == 0 && dma == 0 && direction == 0) cmd = ATA_CMD_READ_PIO;+   if (lba_mode == 1 && dma == 0 && direction == 0) cmd = ATA_CMD_READ_PIO;+   if (lba_mode == 2 && dma == 0 && direction == 0) cmd = ATA_CMD_READ_PIO_EXT;+   if (lba_mode == 0 && dma == 1 && direction == 0) cmd = ATA_CMD_READ_DMA;+   if (lba_mode == 1 && dma == 1 && direction == 0) cmd = ATA_CMD_READ_DMA;+   if (lba_mode == 2 && dma == 1 && direction == 0) cmd = ATA_CMD_READ_DMA_EXT;+   if (lba_mode == 0 && dma == 0 && direction == 1) cmd = ATA_CMD_WRITE_PIO;+   if (lba_mode == 1 && dma == 0 && direction == 1) cmd = ATA_CMD_WRITE_PIO;+   if (lba_mode == 2 && dma == 0 && direction == 1) cmd = ATA_CMD_WRITE_PIO_EXT;+   if (lba_mode == 0 && dma == 1 && direction == 1) cmd = ATA_CMD_WRITE_DMA;+   if (lba_mode == 1 && dma == 1 && direction == 1) cmd = ATA_CMD_WRITE_DMA;+   if (lba_mode == 2 && dma == 1 && direction == 1) cmd = ATA_CMD_WRITE_DMA_EXT;+   ide_write(channel, ATA_REG_COMMAND, cmd);               // Send the Command.++      if (dma) {+      if (direction == 0) {+         // DMA Read.+	  } else {+         // DMA Write.+	  }+	  } else {+      if (direction == 0) {+         // PIO Read.+      for (i = 0; i < numsects; i++) {+//          if ((err = ide_polling(channel, 1)))+            return err; // Polling, set error and exit if there is.+         asm("pushw %es");+         asm("mov %%ax, %%es" : : "a"(selector));+         asm("rep insw" : : "c"(words), "d"(bus), "D"(edi)); // Receive Data.+         asm("popw %es");+         edi += (words*2);+      }+	  }else {+      // PIO Write.+         for (i = 0; i < numsects; i++) {+//             ide_polling(channel, 0); // Polling.+            asm("pushw %ds");+            asm("mov %%ax, %%ds"::"a"(selector));+            asm("rep outsw"::"c"(words), "d"(bus), "S"(edi)); // Send Data+            asm("popw %ds");+            edi += (words*2);+         }+         ide_write(channel, ATA_REG_COMMAND, (char []) {   ATA_CMD_CACHE_FLUSH,+                        ATA_CMD_CACHE_FLUSH,+                        ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);+//          ide_polling(channel, 0); // Polling.+      }+	  }+   return 0; // Easy, isn't it?+}\ No newline at end of fileIndex: kernelpokes.cpp===================================================================--- kernelpokes.cpp	(revision 319)+++ kernelpokes.cpp	(working copy)@@ -10,6 +10,7 @@ KPOKE(settimer); KPOKE(pcicheck); KPOKE(vsync);+KPOKE(diskread); #include "pci.cpp" int init_graph_vga(int width, int height,int chain4); #define SWITCHMODE 0@@ -17,6 +18,7 @@ #define VSYNC 2 #define SETTIMER 3 #define PCICHECK 4+#define DISKREAD 5 /**  * This is for low level testing stuff.  * Meant to be disabled in final version.@@ -34,6 +36,8 @@ 			return POKEK(settimer); 		case PCICHECK: 			return POKEK(pcicheck);+		case DISKREAD:+			return POKEK(diskread); 		default: 			return -Errno::ENOSYS; 	}@@ -43,6 +47,10 @@ timer.set(i1); return 0; }+#include "ata.h"+KPOKE(diskread) {+	return ata_read_test(0x170,0x374);+} KPOKE( vgamode ){  	u32 r=init_graph_vga(i1,i2,i3); 	if(r) { return r; }