int atapi_drive_startstop(uint32 drive,uint32 bus){ printf("\n%s\n","entre"); //Operation code and bit 1 of byte 4 -LoEj(eject)- as 1. uint8 startstop_cmd[12]={0x1B,0,0,0,2,0,0,0,0,0,0,0}; uint8 allowremoval_cmd[12]={0x1E,0,0,0,0,0,0,0,0,0,0,0}; uint8 status; // while((status=inb(ATA_COMMAND(bus))) & 0x80){ // rprintf("while1-busy"); // //BUSY // // If the first bit of the status register (BUSY) isn't 0, the device is busy, // // so keep looping until it isn't. // } // // _Cli(); // while(!((status=inb(ATA_COMMAND(bus))) & 0x60)){ // rprintf("%x%s",status,"2"); // //NOT READY // } // /* DRQ or ERROR */ // if(status & 0x1){ // return -1; // } ata_drive_select (bus, drive); //TODO reemplazar por drive // outb(ATA_DRIVE_SELECT(bus),0x10); //0 master, 10h slave outb(ATA_FEATURES(bus),0); /* Set Nien on device control register to 1 to skip waiting state. nIEN is the second bit from the right here */ // outb(ATA_DCR(bus),0x10); /* Send the ATAPI PACKAGE command to the command register */ outb(ATA_COMMAND(bus),0xA0); //wait 400ns ATA_SELECT_DELAY(bus); while(status=inb(ATA_COMMAND(bus)) & 0x80){ rprintf("while1"); } while(!(status=inb(ATA_COMMAND(bus)) & 0x8)){ rprintf("while2"); //DATA TRANSFER REQUESTED } /* Send ATAPI/SCSI command as 6 words, to the data port */ // outsw(ATA_DATA(bus), (uint16 *)allowremoval_cmd,6); outb(ATA_DATA(bus),0x1E); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); // inb(ATA_DCR(bus)); while(status=inb(ATA_COMMAND(bus)) & 0x80){ rprintf("while1-allow removal"); //BUSY } while(!(status=inb(ATA_COMMAND(bus)) & 0x8)){ rprintf("while2-allow removal"); //DATA TRANSFER REQUESTED } outb(ATA_COMMAND(bus),0xA0); //wait 400ns // ATA_SELECT_DELAY(bus); while(status=inb(ATA_COMMAND(bus)) & 0x80){ rprintf("while1-2"); } while(!(status=inb(ATA_COMMAND(bus)) & 0x8)){ rprintf("while2-2"); //DATA TRANSFER REQUESTED } /* Send ATAPI/SCSI command as 6 words, to the data port */ // outsw(ATA_DATA(bus), (uint16 *)startstop_cmd,6); outb(ATA_DATA(bus),0x1B); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),2); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); outb(ATA_DATA(bus),0); //wait 400ns // ATA_SELECT_DELAY(bus); // inb(ATA_DCR(bus)); while(status=inb(ATA_COMMAND(bus)) & 0x80){ rprintf("while 1 -BUSY- startstop_cmd"); //BUSY } // _Sti(); return 1; }
//---------------------------------------------------------------------- //hyperapp main //---------------------------------------------------------------------- u32 emhf_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb){ LDNPB *pldnPb; #if defined(__LDN_TV_INTEGRATION__) { extern u32 tv_app_main(VCPU *vcpu, APP_PARAM_BLOCK *apb); tv_app_main(vcpu, apb); } #endif //we only perform setup on the BSP if(!vcpu->isbsp){ printf("\nCPU(0x%02x): Lockdown initiaizing. Skipping init on AP.", vcpu->id); return APP_INIT_SUCCESS; } printf("\nCPU(0x%02x): BSP. Lockdown initiaizing...", vcpu->id); //setup guest environment physical memory size LDN_ENV_PHYSICALMEMORYLIMIT = (apb->runtimephysmembase - PAGE_SIZE_2M); #if defined(__LDN_HYPERSWITCHING__) //ACPI initialization ACPIInitializeRegisters(); acpi_control_portnum = (u32)PM1_CNTa; printf("\nCPU(0x%02x): Lockdown; ACPI control port=0x%08x", vcpu->id, acpi_control_portnum); //set I/O port intercept for ACPI control port emhf_partition_legacyIO_setprot(vcpu, acpi_control_portnum, 2, PART_LEGACYIO_NOACCESS); //16-bit port #endif #if defined(__LDN_HYPERPARTITIONING__) //set IDE port intercepts for hyper-partitioning emhf_partition_legacyIO_setprot(vcpu, ATA_COMMAND(ATA_BUS_PRIMARY), 1, PART_LEGACYIO_NOACCESS); //8-bit port emhf_partition_legacyIO_setprot(vcpu, ATA_SECTOR_COUNT(ATA_BUS_PRIMARY), 1, PART_LEGACYIO_NOACCESS); //8-bit port emhf_partition_legacyIO_setprot(vcpu, ATA_LBALOW(ATA_BUS_PRIMARY), 1, PART_LEGACYIO_NOACCESS); //8-bit port emhf_partition_legacyIO_setprot(vcpu, ATA_LBAMID(ATA_BUS_PRIMARY), 1, PART_LEGACYIO_NOACCESS); //8-bit port emhf_partition_legacyIO_setprot(vcpu, ATA_LBAHIGH(ATA_BUS_PRIMARY), 1, PART_LEGACYIO_NOACCESS); //8-bit port printf("\nCPU(0x%02x): Lockdown; Setup hyperpartitioning on \ ATA/SATA device at 0x%08x", vcpu->id, ATA_BUS_PRIMARY); #endif //grab the ldn parameter block from verifier, this tells us the //destination environment characteristics //TODO: verifier integration, for now we just take it from the apb if(apb->optionalmodule_size == 0){ //if we don't have an optional module then load the untrusted //environment currentenvironment = LDN_ENV_UNTRUSTED_SIGNATURE; printf("\nCPU(0x%02x): booting UNTRUSTED environment...", vcpu->id); }else{ //an optional module was specified, so load the trusted //environment pldnPb = (LDNPB *) apb->optionalmodule_ptr; currentenvironment = LDN_ENV_TRUSTED_SIGNATURE; //sanity check we have a good TE parameter block if(pldnPb->signature != LDN_ENV_TRUSTED_SIGNATURE){ printf("\nCPU(0x%02x): unknown destination environment signature (0x%08x), halting!", vcpu->id, pldnPb->signature); HALT(); } printf("\nCPU(0x%02x): booting TRUSTED environment...", vcpu->id); } //check if we are going to the trusted environment, if so enable //approved execution and mask off any network interfaces if(currentenvironment == LDN_ENV_TRUSTED_SIGNATURE){ #if defined(__LDN_APPROVEDEXEC__) //enable approved execution approvedexec_setup(vcpu, apb); #endif #if defined(__LDN_SSLPA__) //mask off all network interfaces by interposing on PCI bus accesses emhf_iopm_set_write(vcpu, PCI_CONFIG_DATA_PORT, 2); //16-bit port #endif }else{ //we are going to run the untrusted environment ASSERT( currentenvironment == LDN_ENV_UNTRUSTED_SIGNATURE); /*//TODO:make EPT entries such that they map 2M pages for the untrusted //environment in order to achieve greatest speedup during EPT //translation vmx_setupEPT2M(vcpu); emhf_hwpgtbl_flushall(vcpu); printf("\nCPU(0x%02x): setup 2M EPT pages");*/ } return APP_INIT_SUCCESS; //successful }
/* Use the ATA IDENTIFY command to find out what kind of drive is * attached to the given bus/slot. */ uint32 ata_identify (uint32 bus, uint32 drive) { uint8 status; uint16 buffer[256]; ata_drive_select (bus, drive); // while(!(status=inb(ATA_COMMAND(bus)) & 0x60)){ // rprintf("loop0"); // } outb (ATA_COMMAND (bus),0xEC); /* Send IDENTIFY command */ ATA_SELECT_DELAY (bus); status = inb (ATA_COMMAND (bus)); if (status == 0) { // rprintf ("ATA bus %X drive %X does not exist\n", bus, drive); return NOTCD; } if (status & 0x1) { /* Drive does not support IDENTIFY. Probably a CD-ROM. */ goto guess_identity; } /* Poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) * clears, and bit 3 (DRQ, value = 8) sets -- or until bit 0 (ERR, * value = 1) sets. */ while ((status = inb (ATA_COMMAND (bus))) & 0x80){ asm volatile ("pause"); // printf("%s\n","busy"); } /* BUSY */ while (!((status = inb (ATA_COMMAND (bus))) & 0x8) && !(status & 0x01)){ // printf("%x",status); asm volatile ("pause"); } if (status & 0x1) { // rprintf ("ATA bus %X drive %X caused error.\n", bus, drive); goto guess_identity; } /* Read 256 words */ insw (ATA_DATA (bus), buffer, 256); #ifdef DEBUG_ATA { int i, j; // DLOG ("IDENTIFY (bus: %X drive: %X) command output:", bus, drive); /* dump to com1 */ for (i = 0; i < 32; i++) { for (j = 0; j < 8; j++) { rprintf ("%.4X ", buffer[i * 32 + j]); } rprintf ("\n"); } } #endif if (buffer[83] & (1 << 10)) // rprintf ("LBA48 mode supported.\n"); // rprintf ("LBA48 addressable sectors: %.4X %.4X %.4X %.4X\n", // buffer[100], buffer[101], buffer[102], buffer[103]); rprintf("not a cd"); return NOTCD; guess_identity:{ uint8 b1, b2; b1 = inb (ATA_ADDRESS2 (bus)); b2 = inb (ATA_ADDRESS3 (bus)); // rprintf ("ata_detect: %.2X %.2X\n", b1, b2); if (b1 == 0x14 && b2 == 0xEB) { rprintf("is a CD"); // rprintf("P-ATAPI detected\n"); return ISCD; } //TODO: probar eliminar estos if (b1 == 0x69 && b2 == 0x96) { rprintf("is a CD"); // rprintf ("S-ATAPI detected\n"); return ISCD; } if (b1 == 0x3C && b2 == 0xC3) { rprintf("is a CD"); // rprintf ("SATA detected\n"); return ISCD; } rprintf("NOT a CD"); return NOTCD; } }
//---------------------------------------------------------------------- //hyperapp I/O port intercept handler //---------------------------------------------------------------------- u32 emhf_app_handleintercept_portaccess(VCPU *vcpu, struct regs *r, u32 portnum, u32 access_type, u32 access_size){ #if defined(__LDN_HYPERSWITCHING__) u32 acpi_sleep_en; if(vcpu->cpu_vendor == CPU_VENDOR_AMD) acpi_sleep_en = (u16)(((struct _svm_vmcbfields *)vcpu->vmcb_vaddr_ptr)->rax) & (u16)(1 << 13); else acpi_sleep_en = ((u16)r->eax & (u16)(1 << 13)); //printf("\nCPU(0x%02x): Lockdown type=%u, portnum=0x%08x, size=%u, sleep_en=%u", // vcpu->id, access_type, portnum, access_size, acpi_sleep_en); if(access_type == IO_TYPE_OUT && portnum == acpi_control_portnum && access_size == IO_SIZE_WORD && acpi_sleep_en ){ printf("\nCPU(0x%02x): Lockdown; ACPI SLEEP_EN signal caught. resetting firmware...", vcpu->id); //reset platform emhf_baseplatform_reboot(vcpu); //we should never get here HALT(); } #else //__LDN_HYPERSWITCHING__ (void)vcpu; (void)r; (void)portnum; (void)access_type; (void)access_size; #endif //__LDN_HYPERSWITCHING__ #if defined(__LDN_HYPERPARTITIONING__) if( portnum == ATA_COMMAND(ATA_BUS_PRIMARY) || portnum == ATA_SECTOR_COUNT(ATA_BUS_PRIMARY) || portnum == ATA_LBALOW(ATA_BUS_PRIMARY) || portnum == ATA_LBAMID(ATA_BUS_PRIMARY) || portnum == ATA_LBAHIGH(ATA_BUS_PRIMARY) ){ u32 retval; //printf("\nATA IO port access:0x%04x", (u16)portnum); retval = hp(vcpu, r, portnum, access_type, access_size); return retval; } #endif #if defined(__LDN_SSLPA__) if(portnum == PCI_CONFIG_DATA_PORT){ //printf("\nCPU(0x%02x): PCI DATA acc, size=%u, type=%u", // vcpu->id, access_size, access_type); pci_config_reg_addr_t pci_addr; pci_addr.bytes = inl((u32)PCI_CONFIG_ADDR_PORT); if(sslpa_isnetworkdevice(pci_addr.fields.bus, pci_addr.fields.device, pci_addr.fields.function)) { if(access_type == IO_TYPE_IN){ u32 retval; printf("\nCPU(0x%02x): N/W device accessed, denying... (t=%u, s=%u, offset=0x%08x)", vcpu->id, access_type, access_size, pci_addr.fields.offset); if(pci_addr.fields.offset == 0) retval=0xFFFFFFFFUL; //no device present else retval=0; //null value for all other configuration registers ASSERT( (access_size == IO_SIZE_BYTE) || (access_size == IO_SIZE_WORD) || (access_size == IO_SIZE_DWORD) ); switch(access_size){ case IO_SIZE_BYTE: r->eax &= 0xFFFFFF00UL; r->eax |= (u8)retval; break; case IO_SIZE_WORD: r->eax &= 0xFFFF0000UL; r->eax |= (u16)retval; break; case IO_SIZE_DWORD: r->eax = retval; break; } return APP_IOINTERCEPT_SKIP; }else{ printf("\nCPU(0x%02x): N/W device forced write? HALT! (t=%u, s=%u, offset=0x%08x)", vcpu->id, access_type, access_size, pci_addr.fields.offset); HALT(); } } } #endif return APP_IOINTERCEPT_CHAIN; //chain and do the required I/O }