diff options
-rw-r--r-- | SConscript | 2 | ||||
-rw-r--r-- | dev/ns_gige.cc | 272 | ||||
-rw-r--r-- | dev/ns_gige.hh | 39 | ||||
-rw-r--r-- | dev/ns_gige_reg.h | 17 | ||||
-rw-r--r-- | dev/pcidev.hh | 2 | ||||
-rw-r--r-- | dev/sinic.cc | 3 | ||||
-rw-r--r-- | dev/tsunamireg.h | 12 | ||||
-rw-r--r-- | kern/freebsd/freebsd_system.cc | 158 | ||||
-rw-r--r-- | kern/freebsd/freebsd_system.hh | 47 | ||||
-rw-r--r-- | kern/kernel_stats.cc | 5 | ||||
-rw-r--r-- | kern/kernel_stats.hh | 4 | ||||
-rw-r--r-- | kern/linux/aligned.hh | 3 | ||||
-rw-r--r-- | kern/linux/linux_system.cc | 4 | ||||
-rw-r--r-- | kern/linux/linux_system.hh | 4 | ||||
-rw-r--r-- | kern/linux/linux_threadinfo.hh | 2 | ||||
-rw-r--r-- | kern/linux/printk.cc | 4 | ||||
-rw-r--r-- | kern/linux/sched.hh | 3 | ||||
-rw-r--r-- | kern/linux/thread_info.hh | 1 | ||||
-rw-r--r-- | kern/system_events.cc | 5 | ||||
-rw-r--r-- | kern/system_events.hh | 2 | ||||
-rw-r--r-- | python/m5/config.py | 22 | ||||
-rwxr-xr-x | util/pbs/job.py | 36 | ||||
-rwxr-xr-x | util/pbs/send.py | 69 |
23 files changed, 602 insertions, 114 deletions
diff --git a/SConscript b/SConscript index 8a983840d..13a0fe0df 100644 --- a/SConscript +++ b/SConscript @@ -267,7 +267,7 @@ full_system_sources = Split(''' dev/pcidev.cc dev/pcifake.cc dev/pktfifo.cc - dev/platform.cc + dev/platform.cc dev/sinic.cc dev/simple_disk.cc dev/tsunami.cc diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 03942cb62..304263695 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -98,14 +98,14 @@ NSGigE::NSGigE(Params *p) txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), rxEnable(false), CRDD(false), rxPktBytes(0), rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), - rxDmaReadEvent(this), rxDmaWriteEvent(this), + eepromState(eepromStart), rxDmaReadEvent(this), rxDmaWriteEvent(this), txDmaReadEvent(this), txDmaWriteEvent(this), dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), txDelay(p->tx_delay), rxDelay(p->rx_delay), rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this), txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), - acceptPerfect(false), acceptArp(false), + acceptPerfect(false), acceptArp(false), multicastHashEnable(false), physmem(p->pmem), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { @@ -680,7 +680,9 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) break; case RFDR: - switch (regs.rfcr & RFCR_RFADDR) { + uint16_t rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); + switch (rfaddr) { + // Read from perfect match ROM octets case 0x000: reg = rom.perfectMatch[1]; reg = reg << 8; @@ -695,9 +697,21 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) reg += rom.perfectMatch[4]; break; default: - panic("reading RFDR for something other than PMATCH!\n"); - // didn't implement other RFDR functionality b/c - // driver didn't use it + // Read filter hash table + if (rfaddr >= FHASH_ADDR && + rfaddr < FHASH_ADDR + FHASH_SIZE) { + + // Only word-aligned reads supported + if (rfaddr % 2) + panic("unaligned read from filter hash table!"); + + reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; + reg += rom.filterHash[rfaddr - FHASH_ADDR]; + break; + } + + panic("reading RFDR for something other than pattern\ + matching or hashing! %#x\n", rfaddr); } break; @@ -838,8 +852,12 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) reg & CFGR_RESERVED || reg & CFGR_T64ADDR || reg & CFGR_PCI64_DET) - panic("writing to read-only or reserved CFGR bits!\n"); + // First clear all writable bits + regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | + CFGR_RESERVED | CFGR_T64ADDR | + CFGR_PCI64_DET; + // Now set the appropriate writable bits regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS | CFGR_RESERVED | CFGR_T64ADDR | CFGR_PCI64_DET); @@ -895,15 +913,27 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) break; case MEAR: - regs.mear = reg; + // Clear writable bits + regs.mear &= MEAR_EEDO; + // Set appropriate writable bits + regs.mear |= reg & ~MEAR_EEDO; + + // FreeBSD uses the EEPROM to read PMATCH (for the MAC address) + // even though it could get it through RFDR + if (reg & MEAR_EESEL) { + // Rising edge of clock + if (reg & MEAR_EECLK && !eepromClk) + eepromKick(); + } + else { + eepromState = eepromStart; + regs.mear &= ~MEAR_EEDI; + } + + eepromClk = reg & MEAR_EECLK; + // since phy is completely faked, MEAR_MD* don't matter - // and since the driver never uses MEAR_EE*, they don't - // matter #if 0 - if (reg & MEAR_EEDI) ; - if (reg & MEAR_EEDO) ; // this one is read only - if (reg & MEAR_EECLK) ; - if (reg & MEAR_EESEL) ; if (reg & MEAR_MDIO) ; if (reg & MEAR_MDDIR) ; if (reg & MEAR_MDC) ; @@ -980,7 +1010,11 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) break; case GPIOR: - regs.gpior = reg; + // Only write writable bits + regs.gpior &= GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN + | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN; + regs.gpior |= reg & ~(GPIOR_UNUSED | GPIOR_GP5_IN | GPIOR_GP4_IN + | GPIOR_GP3_IN | GPIOR_GP2_IN | GPIOR_GP1_IN); /* these just control general purpose i/o pins, don't matter */ break; @@ -1037,14 +1071,14 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) acceptUnicast = (reg & RFCR_AAU) ? true : false; acceptPerfect = (reg & RFCR_APM) ? true : false; acceptArp = (reg & RFCR_AARP) ? true : false; + multicastHashEnable = (reg & RFCR_MHEN) ? true : false; #if 0 if (reg & RFCR_APAT) panic("RFCR_APAT not implemented!\n"); #endif - - if (reg & RFCR_MHEN || reg & RFCR_UHEN) - panic("hash filtering not implemented!\n"); + if (reg & RFCR_UHEN) + panic("Unicast hash filtering not used by drivers!\n"); if (reg & RFCR_ULM) panic("RFCR_ULM not implemented!\n"); @@ -1052,10 +1086,41 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) break; case RFDR: - panic("the driver never writes to RFDR, something is wrong!\n"); + uint16_t rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); + switch (rfaddr) { + case 0x000: + rom.perfectMatch[0] = (uint8_t)reg; + rom.perfectMatch[1] = (uint8_t)(reg >> 8); + break; + case 0x002: + rom.perfectMatch[2] = (uint8_t)reg; + rom.perfectMatch[3] = (uint8_t)(reg >> 8); + break; + case 0x004: + rom.perfectMatch[4] = (uint8_t)reg; + rom.perfectMatch[5] = (uint8_t)(reg >> 8); + break; + default: + + if (rfaddr >= FHASH_ADDR && + rfaddr < FHASH_ADDR + FHASH_SIZE) { + + // Only word-aligned writes supported + if (rfaddr % 2) + panic("unaligned write to filter hash table!"); + + rom.filterHash[rfaddr - FHASH_ADDR] = (uint8_t)reg; + rom.filterHash[rfaddr - FHASH_ADDR + 1] + = (uint8_t)(reg >> 8); + break; + } + panic("writing RFDR for something other than pattern matching\ + or hashing! %#x\n", rfaddr); + } case BRAR: - panic("the driver never uses BRAR, something is wrong!\n"); + regs.brar = reg; + break; case BRDR: panic("the driver never uses BRDR, something is wrong!\n"); @@ -1076,7 +1141,6 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) case VDR: panic("the driver never uses VDR, something is wrong!\n"); - break; case CCSR: /* not going to implement clockrun stuff */ @@ -1103,12 +1167,16 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) panic("TBISR is read only register!\n"); case TANAR: - regs.tanar = reg; - if (reg & TANAR_PS2) - panic("this isn't used in driver, something wrong!\n"); + // Only write the writable bits + regs.tanar &= TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED; + regs.tanar |= reg & ~(TANAR_RF1 | TANAR_RF2 | TANAR_UNUSED); + + // Pause capability unimplemented +#if 0 + if (reg & TANAR_PS2) ; + if (reg & TANAR_PS1) ; +#endif - if (reg & TANAR_PS1) - panic("this isn't used in driver, something wrong!\n"); break; case TANLPAR: @@ -1361,7 +1429,7 @@ NSGigE::regsReset() { memset(®s, 0, sizeof(regs)); regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000); - regs.mear = 0x22; + regs.mear = 0x12; regs.txcfg = 0x120; // set drain threshold to 1024 bytes and // fill threshold to 32 bytes regs.rxcfg = 0x4; // set drain threshold to 16 bytes @@ -1369,6 +1437,7 @@ NSGigE::regsReset() regs.mibc = MIBC_FRZ; regs.vdr = 0x81; // set the vlan tag type to 802.1q regs.tesr = 0xc000; // TBI capable of both full and half duplex + regs.brar = 0xffffffff; extstsEnable = false; acceptBroadcast = false; @@ -2248,6 +2317,107 @@ NSGigE::txKick() txKickEvent.schedule(txKickTick); } +/** + * Advance the EEPROM state machine + * Called on rising edge of EEPROM clock bit in MEAR + */ +void +NSGigE::eepromKick() +{ + switch (eepromState) { + + case eepromStart: + + // Wait for start bit + if (regs.mear & MEAR_EEDI) { + // Set up to get 2 opcode bits + eepromState = eepromGetOpcode; + eepromBitsToRx = 2; + eepromOpcode = 0; + } + break; + + case eepromGetOpcode: + eepromOpcode <<= 1; + eepromOpcode += (regs.mear & MEAR_EEDI) ? 1 : 0; + --eepromBitsToRx; + + // Done getting opcode + if (eepromBitsToRx == 0) { + if (eepromOpcode != EEPROM_READ) + panic("only EEPROM reads are implemented!"); + + // Set up to get address + eepromState = eepromGetAddress; + eepromBitsToRx = 6; + eepromAddress = 0; + } + break; + + case eepromGetAddress: + eepromAddress <<= 1; + eepromAddress += (regs.mear & MEAR_EEDI) ? 1 : 0; + --eepromBitsToRx; + + // Done getting address + if (eepromBitsToRx == 0) { + + if (eepromAddress >= EEPROM_SIZE) + panic("EEPROM read access out of range!"); + + switch (eepromAddress) { + + case EEPROM_PMATCH2_ADDR: + eepromData = rom.perfectMatch[5]; + eepromData <<= 8; + eepromData += rom.perfectMatch[4]; + break; + + case EEPROM_PMATCH1_ADDR: + eepromData = rom.perfectMatch[3]; + eepromData <<= 8; + eepromData += rom.perfectMatch[2]; + break; + + case EEPROM_PMATCH0_ADDR: + eepromData = rom.perfectMatch[1]; + eepromData <<= 8; + eepromData += rom.perfectMatch[0]; + break; + + default: + panic("FreeBSD driver only uses EEPROM to read PMATCH!"); + } + // Set up to read data + eepromState = eepromRead; + eepromBitsToRx = 16; + + // Clear data in bit + regs.mear &= ~MEAR_EEDI; + } + break; + + case eepromRead: + // Clear Data Out bit + regs.mear &= ~MEAR_EEDO; + // Set bit to value of current EEPROM bit + regs.mear |= (eepromData & 0x8000) ? MEAR_EEDO : 0x0; + + eepromData <<= 1; + --eepromBitsToRx; + + // All done + if (eepromBitsToRx == 0) { + eepromState = eepromStart; + } + break; + + default: + panic("invalid EEPROM state"); + } + +} + void NSGigE::transferDone() { @@ -2294,6 +2464,9 @@ NSGigE::rxFilter(const PacketPtr &packet) if (acceptMulticast) drop = false; + // Multicast hashing faked - all packets accepted + if (multicastHashEnable) + drop = false; } if (drop) { @@ -2319,7 +2492,14 @@ NSGigE::recvPacket(PacketPtr packet) return true; } - if (rxFilterEnable && rxFilter(packet)) { + if (!rxFilterEnable) { + DPRINTF(Ethernet, + "receive packet filtering disabled . . . packet dropped\n"); + interface->recvDone(); + return true; + } + + if (rxFilter(packet)) { DPRINTF(Ethernet, "packet filtered...dropped\n"); interface->recvDone(); return true; @@ -2394,6 +2574,8 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(regs.pcr); SERIALIZE_SCALAR(regs.rfcr); SERIALIZE_SCALAR(regs.rfdr); + SERIALIZE_SCALAR(regs.brar); + SERIALIZE_SCALAR(regs.brdr); SERIALIZE_SCALAR(regs.srr); SERIALIZE_SCALAR(regs.mibc); SERIALIZE_SCALAR(regs.vrcr); @@ -2408,6 +2590,7 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(regs.tesr); SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); + SERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); SERIALIZE_SCALAR(ioEnable); @@ -2481,6 +2664,17 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(rxKickTick); /* + * Serialize EEPROM state machine + */ + int eepromState = this->eepromState; + SERIALIZE_SCALAR(eepromState); + SERIALIZE_SCALAR(eepromClk); + SERIALIZE_SCALAR(eepromBitsToRx); + SERIALIZE_SCALAR(eepromOpcode); + SERIALIZE_SCALAR(eepromAddress); + SERIALIZE_SCALAR(eepromData); + + /* * If there's a pending transmit, store the time so we can * reschedule it later */ @@ -2496,6 +2690,7 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(acceptUnicast); SERIALIZE_SCALAR(acceptPerfect); SERIALIZE_SCALAR(acceptArp); + SERIALIZE_SCALAR(multicastHashEnable); /* * Keep track of pending interrupt status. @@ -2535,6 +2730,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(regs.pcr); UNSERIALIZE_SCALAR(regs.rfcr); UNSERIALIZE_SCALAR(regs.rfdr); + UNSERIALIZE_SCALAR(regs.brar); + UNSERIALIZE_SCALAR(regs.brdr); UNSERIALIZE_SCALAR(regs.srr); UNSERIALIZE_SCALAR(regs.mibc); UNSERIALIZE_SCALAR(regs.vrcr); @@ -2549,6 +2746,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(regs.tesr); UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); + UNSERIALIZE_ARRAY(rom.filterHash, FHASH_SIZE); UNSERIALIZE_SCALAR(ioEnable); @@ -2635,7 +2833,19 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) if (rxKickTick) rxKickEvent.schedule(rxKickTick); - /* + /* + * Unserialize EEPROM state machine + */ + int eepromState; + UNSERIALIZE_SCALAR(eepromState); + this->eepromState = (EEPROMState) eepromState; + UNSERIALIZE_SCALAR(eepromClk); + UNSERIALIZE_SCALAR(eepromBitsToRx); + UNSERIALIZE_SCALAR(eepromOpcode); + UNSERIALIZE_SCALAR(eepromAddress); + UNSERIALIZE_SCALAR(eepromData); + + /* * If there's a pending transmit, reschedule it now */ Tick transmitTick; @@ -2652,6 +2862,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(acceptUnicast); UNSERIALIZE_SCALAR(acceptPerfect); UNSERIALIZE_SCALAR(acceptArp); + UNSERIALIZE_SCALAR(multicastHashEnable); /* * Keep track of pending interrupt status. @@ -2756,8 +2967,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), - INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", - "00:99:00:00:00:01"), + INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL), INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 805d4c8cb..ac16aa266 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -45,6 +45,17 @@ #include "mem/bus/bus.hh" #include "sim/eventq.hh" +// Hash filtering constants +const uint16_t FHASH_ADDR = 0x100; +const uint16_t FHASH_SIZE = 0x100; + +// EEPROM constants +const uint8_t EEPROM_READ = 0x2; +const uint8_t EEPROM_SIZE = 64; // Size in words of NSC93C46 EEPROM +const uint8_t EEPROM_PMATCH2_ADDR = 0xA; // EEPROM Address of PMATCH word 2 +const uint8_t EEPROM_PMATCH1_ADDR = 0xB; // EEPROM Address of PMATCH word 1 +const uint8_t EEPROM_PMATCH0_ADDR = 0xC; // EEPROM Address of PMATCH word 0 + /** * Ethernet device registers */ @@ -69,6 +80,8 @@ struct dp_regs { uint32_t pcr; uint32_t rfcr; uint32_t rfdr; + uint32_t brar; + uint32_t brdr; uint32_t srr; uint32_t mibc; uint32_t vrcr; @@ -89,6 +102,12 @@ struct dp_rom { * the linux driver doesn't use any other ROM */ uint8_t perfectMatch[ETH_ADDR_LEN]; + + /** + * for hash table memory. + * used by the freebsd driver + */ + uint8_t filterHash[FHASH_SIZE]; }; class NSGigEInt; @@ -137,6 +156,15 @@ class NSGigE : public PciDev dmaWriteWaiting }; + /** EEPROM State Machine States */ + enum EEPROMState + { + eepromStart, + eepromGetOpcode, + eepromGetAddress, + eepromRead + }; + private: Addr addr; static const Addr size = sizeof(dp_regs); @@ -211,6 +239,14 @@ class NSGigE : public PciDev bool extstsEnable; + /** EEPROM State Machine */ + EEPROMState eepromState; + bool eepromClk; + uint8_t eepromBitsToRx; + uint8_t eepromOpcode; + uint8_t eepromAddress; + uint16_t eepromData; + protected: Tick dmaReadDelay; Tick dmaWriteDelay; @@ -274,6 +310,8 @@ class NSGigE : public PciDev friend void TxKickEvent::process(); TxKickEvent txKickEvent; + void eepromKick(); + /** * Retransmit event */ @@ -301,6 +339,7 @@ class NSGigE : public PciDev bool acceptUnicast; bool acceptPerfect; bool acceptArp; + bool multicastHashEnable; PhysicalMemory *physmem; diff --git a/dev/ns_gige_reg.h b/dev/ns_gige_reg.h index c797285dc..77b12dbd8 100644 --- a/dev/ns_gige_reg.h +++ b/dev/ns_gige_reg.h @@ -196,12 +196,21 @@ #define TX_CFG_DRTH_MASK 0x000000ff /*general purpose I/O control register */ +#define GPIOR_UNUSED 0xffff8000 +#define GPIOR_GP5_IN 0x00004000 +#define GPIOR_GP4_IN 0x00002000 +#define GPIOR_GP3_IN 0x00001000 +#define GPIOR_GP2_IN 0x00000800 +#define GPIOR_GP1_IN 0x00000400 #define GPIOR_GP5_OE 0x00000200 #define GPIOR_GP4_OE 0x00000100 #define GPIOR_GP3_OE 0x00000080 #define GPIOR_GP2_OE 0x00000040 #define GPIOR_GP1_OE 0x00000020 +#define GPIOR_GP5_OUT 0x00000010 +#define GPIOR_GP4_OUT 0x00000008 #define GPIOR_GP3_OUT 0x00000004 +#define GPIOR_GP2_OUT 0x00000002 #define GPIOR_GP1_OUT 0x00000001 /* receive configuration register */ @@ -283,10 +292,14 @@ #define TBISR_MR_AN_COMPLETE 0x00000004 /* TBI auto-negotiation advertisement register */ +#define TANAR_NP 0x00008000 +#define TANAR_RF2 0x00002000 +#define TANAR_RF1 0x00001000 #define TANAR_PS2 0x00000100 #define TANAR_PS1 0x00000080 -#define TANAR_HALF_DUP 0x00000040 -#define TANAR_FULL_DUP 0x00000020 +#define TANAR_HALF_DUP 0x00000040 +#define TANAR_FULL_DUP 0x00000020 +#define TANAR_UNUSED 0x00000E1F /* * descriptor format currently assuming link and bufptr diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 4293c59b9..433079b61 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -121,7 +121,7 @@ class PciDev : public DmaDevice protected: /** The current config space. Unlike the PciConfigData this is - * updated during simulation while continues to refelect what was + * updated during simulation while continues to reflect what was * in the config file. */ PCIConfig config; diff --git a/dev/sinic.cc b/dev/sinic.cc index d30303835..1914367bd 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -1403,8 +1403,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device) INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), - INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", - "00:99:00:00:00:01"), + INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL), INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h index 583ff78b4..a10259900 100644 --- a/dev/tsunamireg.h +++ b/dev/tsunamireg.h @@ -131,6 +131,18 @@ #define TSDEV_DMA1_MMASK 0x0F #define TSDEV_DMA2_MMASK 0xDE +/* Added for keyboard accesses */ +#define TSDEV_KBD 0x64 + +/* Added for ATA PCI DMA */ +#define ATA_PCI_DMA 0x00 +#define ATA_PCI_DMA2 0x02 +#define ATA_PCI_DMA3 0x16 +#define ATA_PCI_DMA4 0x17 +#define ATA_PCI_DMA5 0x1a +#define ATA_PCI_DMA6 0x11 +#define ATA_PCI_DMA7 0x14 + #define TSDEV_RTC_ADDR 0x70 #define TSDEV_RTC_DATA 0x71 diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc new file mode 100644 index 000000000..35ac14330 --- /dev/null +++ b/kern/freebsd/freebsd_system.cc @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Modifications for the FreeBSD kernel. + * Based on kern/linux/linux_system.cc. + * + */ + +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "kern/freebsd/freebsd_system.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/builder.hh" +#include "targetarch/vtophys.hh" + +using namespace std; + +FreebsdSystem::FreebsdSystem(Params *p) + : System(p) +{ + Addr addr = 0; + + /** + * Any time DELAY is called just skip the function. + */ + skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY"); + if (kernelSymtab->findAddress("DELAY", addr)) + skipDelayEvent->schedule(addr+sizeof(MachInst)); + + skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks"); + if (kernelSymtab->findAddress("calibrate_clocks", addr)) + skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2); +} + + +FreebsdSystem::~FreebsdSystem() +{ + delete skipDelayEvent; + delete skipCalibrateClocks; +} + + +void +FreebsdSystem::doCalibrateClocks(ExecContext *xc) +{ + Addr ppc_vaddr = 0; + Addr timer_vaddr = 0; + Addr ppc_paddr = 0; + Addr timer_paddr = 0; + + ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1]; + timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2]; + + ppc_paddr = vtophys(physmem, ppc_vaddr); + timer_paddr = vtophys(physmem, timer_vaddr); + + uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); + uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); + + *(uint32_t *)ppc = htoa((uint32_t)2000000000); + *(uint32_t *)timer = htoa((uint32_t)1193180); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<string> kernel; + Param<string> console; + Param<string> pal; + + Param<string> boot_osflags; + Param<string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<string> binned_fns; + Param<bool> bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) + +CREATE_SIM_OBJECT(FreebsdSystem) +{ + System::Params *p = new System::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new FreebsdSystem(p); +} + +REGISTER_SIM_OBJECT("FreebsdSystem", FreebsdSystem) + diff --git a/kern/freebsd/freebsd_system.hh b/kern/freebsd/freebsd_system.hh new file mode 100644 index 000000000..6429b5690 --- /dev/null +++ b/kern/freebsd/freebsd_system.hh @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ +#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ + +#include "kern/freebsd/freebsd_events.hh" + +class FreebsdSystem : public System +{ + private: + SkipFuncEvent *skipDelayEvent; + FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks; + + public: + FreebsdSystem(Params *p); + ~FreebsdSystem(); + void doCalibrateClocks(ExecContext *xc); + +}; + +#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 6e4a77f4e..3a7d12443 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -32,13 +32,8 @@ #include "arch/alpha/osfpal.hh" #include "base/trace.hh" -#include "base/statistics.hh" -#include "base/stats/bin.hh" #include "cpu/exec_context.hh" -#include "cpu/pc_event.hh" -#include "cpu/static_inst.hh" #include "kern/kernel_stats.hh" -#include "kern/linux/linux_syscalls.hh" #include "kern/tru64/tru64_syscalls.hh" using namespace std; diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 66364d2d7..7b931ef79 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -34,10 +34,6 @@ #include <string> #include <vector> -#include "base/statistics.hh" -#include "sim/serialize.hh" -#include "targetarch/isa_traits.hh" - class BaseCPU; class ExecContext; class FnEvent; diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh index 426299b5d..18d1b43c0 100644 --- a/kern/linux/aligned.hh +++ b/kern/linux/aligned.hh @@ -30,9 +30,6 @@ #define __KERN_LINUX_ALIGNED_HH__ -#include "sim/host.hh" -#include "targetarch/isa_traits.hh" - /* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine * as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is * the work around. diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index fd444341a..3f360efdd 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -36,19 +36,15 @@ */ #include "base/loader/symtab.hh" -#include "base/trace.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" #include "kern/linux/linux_events.hh" #include "kern/linux/linux_system.hh" -#include "kern/system_events.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" #include "dev/platform.hh" -#include "targetarch/isa_traits.hh" #include "targetarch/vtophys.hh" -#include "sim/debug.hh" using namespace std; diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index f870b7744..32b92f310 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -29,10 +29,6 @@ #ifndef __KERN_LINUX_LINUX_SYSTEM_HH__ #define __KERN_LINUX_LINUX_SYSTEM_HH__ -#include "sim/host.hh" -#include "sim/system.hh" -#include "targetarch/isa_traits.hh" - /** * MAGIC address where the kernel arguments should go. Defined as * PARAM in linux kernel alpha-asm. diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh index 92cc181db..253b122bc 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/kern/linux/linux_threadinfo.hh @@ -30,9 +30,7 @@ #define __LINUX_TREADNIFO_HH__ -#include "targetarch/isa_traits.hh" #include "targetarch/vptr.hh" -#include "cpu/exec_context.hh" #include "kern/linux/thread_info.hh" #include "kern/linux/sched.hh" diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc index cafc9172a..fbc8bdad1 100644 --- a/kern/linux/printk.cc +++ b/kern/linux/printk.cc @@ -29,12 +29,8 @@ #include <sys/types.h> #include <algorithm> -#include "base/cprintf.hh" #include "base/trace.hh" -#include "sim/host.hh" #include "targetarch/arguments.hh" -#include "targetarch/vtophys.hh" -#include "kern/linux/printk.hh" using namespace std; diff --git a/kern/linux/sched.hh b/kern/linux/sched.hh index e3febb298..a11fa590d 100644 --- a/kern/linux/sched.hh +++ b/kern/linux/sched.hh @@ -29,9 +29,6 @@ #ifndef __KERN_LINUX_SCHED_HH__ #define __KERN_LINUX_SCHED_HH__ -#include "targetarch/isa_traits.hh" -#include "kern/linux/aligned.hh" - namespace Linux { struct task_struct { uint8_t junk1[0xf4]; diff --git a/kern/linux/thread_info.hh b/kern/linux/thread_info.hh index c8bcc726a..cf24ef939 100644 --- a/kern/linux/thread_info.hh +++ b/kern/linux/thread_info.hh @@ -30,7 +30,6 @@ #define __KERN_LINUX_THREAD_INFO_H__ #include "kern/linux/hwrpb.hh" -#include "kern/linux/aligned.hh" namespace Linux { struct thread_info { diff --git a/kern/system_events.cc b/kern/system_events.cc index 40c223b5e..d5c0d242a 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -26,13 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cpu/exec_context.hh" -#include "cpu/base.hh" -#include "encumbered/cpu/full/bpred.hh" #include "encumbered/cpu/full/cpu.hh" #include "kern/kernel_stats.hh" -#include "kern/system_events.hh" -#include "sim/system.hh" void SkipFuncEvent::process(ExecContext *xc) diff --git a/kern/system_events.hh b/kern/system_events.hh index 24aa8f154..94f6efeba 100644 --- a/kern/system_events.hh +++ b/kern/system_events.hh @@ -29,8 +29,6 @@ #ifndef __SYSTEM_EVENTS_HH__ #define __SYSTEM_EVENTS_HH__ -#include "cpu/pc_event.hh" - class System; class SkipFuncEvent : public PCEvent diff --git a/python/m5/config.py b/python/m5/config.py index a281feccc..3c49421d3 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -417,6 +417,9 @@ class SimObject(object): found_obj = match_obj return found_obj, found_obj != None + def unproxy(self, base): + return self + def print_ini(self): print '[' + self.path() + ']' # .ini section header @@ -632,7 +635,7 @@ class AnyProxy(BaseProxy): return 'any' def isproxy(obj): - if isinstance(obj, BaseProxy): + if isinstance(obj, (BaseProxy, EthernetAddr)): return True elif isinstance(obj, (list, tuple)): for v in obj: @@ -980,12 +983,11 @@ def IncEthernetAddr(addr, val = 1): return ':'.join(map(lambda x: '%02x' % x, bytes)) class NextEthernetAddr(object): - __metaclass__ = Singleton addr = "00:90:00:00:00:01" def __init__(self, inc = 1): - self.value = self.addr - self.addr = IncEthernetAddr(self.addr, inc) + self.value = NextEthernetAddr.addr + NextEthernetAddr.addr = IncEthernetAddr(NextEthernetAddr.addr, inc) class EthernetAddr(ParamValue): def __init__(self, value): @@ -1006,10 +1008,16 @@ class EthernetAddr(ParamValue): self.value = value + def unproxy(self, base): + if self.value == NextEthernetAddr: + self.addr = self.value().value + return self + def __str__(self): if self.value == NextEthernetAddr: - self.value = self.value().value - return self.value + return self.addr + else: + return self.value # Special class for NULL pointers. Note the special check in # make_param_value() above that lets these be assigned where a @@ -1027,7 +1035,7 @@ class NullSimObject(object): def ini_str(self): return 'Null' - def unproxy(self,base): + def unproxy(self, base): return self def set_path(self, parent, name): diff --git a/util/pbs/job.py b/util/pbs/job.py index 4ead50de9..f370862de 100755 --- a/util/pbs/job.py +++ b/util/pbs/job.py @@ -83,37 +83,35 @@ def readval(filename): if __name__ == '__main__': rootdir = env.setdefault('ROOTDIR', os.getcwd()) - jobid = env['PBS_JOBID'] - jobname = env['PBS_JOBNAME'] - jobdir = joinpath(rootdir, jobname) + pbs_jobid = env['PBS_JOBID'] + pbs_jobname = env['PBS_JOBNAME'] basedir = joinpath(rootdir, 'Base') - user = env['USER'] - + jobname = env.setdefault('JOBNAME', pbs_jobname) + jobfile = env.setdefault('JOBFILE', joinpath(basedir, 'test.py')) + outdir = env.setdefault('OUTPUT_DIR', joinpath(rootdir, jobname)) env['POOLJOB'] = 'True' - env['OUTPUT_DIR'] = jobdir - env['JOBFILE'] = joinpath(basedir, 'test.py') - env['JOBNAME'] = jobname + + if os.path.isdir("/work"): + workbase = "/work" + else: + workbase = "/tmp/" + + workdir = joinpath(workbase, '%s.%s' % (env['USER'], pbs_jobid)) def echofile(filename, string): try: - f = file(joinpath(jobdir, filename), 'w') + f = file(joinpath(outdir, filename), 'w') print >>f, string f.flush() f.close() except IOError,e: sys.exit(e) - if os.path.isdir("/work"): - workbase = "/work" - else: - workbase = "/tmp/" - - workdir = joinpath(workbase, '%s.%s' % (user, jobid)) - os.umask(0022) echofile('.start', date()) - echofile('.jobid', jobid) + echofile('.pbs_jobid', pbs_jobid) + echofile('.pbs_jobname', pbs_jobid) echofile('.host', socket.gethostname()) if os.path.isdir(workdir): @@ -132,7 +130,7 @@ if __name__ == '__main__': except OSError,e: sys.exit(e) - os.symlink(joinpath(jobdir, 'output'), 'status.out') + os.symlink(joinpath(outdir, 'output'), 'status.out') args = [ joinpath(basedir, 'm5'), joinpath(basedir, 'run.py') ] if not len(args): @@ -147,7 +145,7 @@ if __name__ == '__main__': if not childpid: # Execute command sys.stdin.close() - fd = os.open(joinpath(jobdir, "output"), + fd = os.open(joinpath(outdir, "output"), os.O_WRONLY | os.O_CREAT | os.O_TRUNC) os.dup2(fd, sys.stdout.fileno()) os.dup2(fd, sys.stderr.fileno()) diff --git a/util/pbs/send.py b/util/pbs/send.py index f8ca5209c..ecb0be0ec 100755 --- a/util/pbs/send.py +++ b/util/pbs/send.py @@ -30,9 +30,9 @@ import os, os.path, re, socket, sys from os import environ as env, listdir -from os.path import basename, isdir, isfile, islink, join as joinpath +from os.path import basename, isdir, isfile, islink, join as joinpath, normpath from filecmp import cmp as filecmp -from shutil import copyfile +from shutil import copy def nfspath(dir): if dir.startswith('/.automount/'): @@ -41,6 +41,38 @@ def nfspath(dir): dir = '/n/%s%s' % (socket.gethostname().split('.')[0], dir) return dir +def syncdir(srcdir, destdir): + srcdir = normpath(srcdir) + destdir = normpath(destdir) + if not isdir(destdir): + sys.exit('destination directory "%s" does not exist' % destdir) + + for root, dirs, files in os.walk(srcdir): + root = normpath(root) + prefix = os.path.commonprefix([root, srcdir]) + root = root[len(prefix):] + if root.startswith('/'): + root = root[1:] + for rem in [ d for d in dirs if d.startswith('.') or d == 'SCCS']: + dirs.remove(rem) + + for entry in dirs: + newdir = joinpath(destdir, root, entry) + if not isdir(newdir): + os.mkdir(newdir) + print 'mkdir', newdir + + for i,d in enumerate(dirs): + if islink(joinpath(srcdir, root, d)): + dirs[i] = joinpath(d, '.') + + for entry in files: + dest = normpath(joinpath(destdir, root, entry)) + src = normpath(joinpath(srcdir, root, entry)) + if not isfile(dest) or not filecmp(src, dest): + print 'copy %s %s' % (dest, src) + copy(src, dest) + progpath = nfspath(sys.path[0]) progname = basename(sys.argv[0]) usage = """\ @@ -107,16 +139,7 @@ for arg in args: if not listonly and not onlyecho and isdir(linkdir): if verbose: print 'Checking for outdated files in Link directory' - entries = listdir(linkdir) - for entry in entries: - link = joinpath(linkdir, entry) - if not islink(link) or not isfile(link): - continue - - base = joinpath(basedir, entry) - if not isfile(base) or not filecmp(link, base): - print 'Base/%s is different than Link/%s: copying' % (entry, entry) - copyfile(link, base) + syncdir(linkdir, basedir) import job, jobfile, pbs @@ -164,6 +187,21 @@ if not onlyecho: jl.append(jobname) joblist = jl +def setname(jobid, jobname): + # since pbs can handle jobnames of 15 characters or less, don't + # use the raj hack. + if len(jobname) <= 15: + return + + import socket + s = socket.socket() + # Connect to pbs.pool and send the jobid/jobname pair to port + # 24465 (Raj didn't realize that there are only 64k ports and + # setup inetd to point to port 90001) + s.connect(("pbs.pool", 24465)) + s.send("%s %s\n" % (jobid, jobname)) + s.close() + for jobname in joblist: jobdir = joinpath(rootdir, jobname) @@ -176,10 +214,11 @@ for jobname in joblist: qsub = pbs.qsub() qsub.pbshost = 'simpool.eecs.umich.edu' qsub.stdout = joinpath(jobdir, 'jobout') - qsub.name = jobname + qsub.name = jobname[:15] qsub.join = True qsub.node_type = 'FAST' qsub.env['ROOTDIR'] = rootdir + qsub.env['JOBNAME'] = jobname if len(queue): qsub.queue = queue qsub.build(joinpath(progpath, 'job.py')) @@ -190,6 +229,8 @@ for jobname in joblist: if not onlyecho: ec = qsub.do() if ec == 0: - print 'PBS Jobid: %s' % qsub.result + jobid = qsub.result + print 'PBS Jobid: %s' % jobid + setname(jobid, jobname) else: print 'PBS Failed' |