/* * i8259_init * DESCRIPTION: Initialize the 8259 PIC * INPUTS: none * OUTPUTS: none * RETURN VALUE: none * SIDE EFFECTS: Output bits to 8259 chip */ void i8259_init(void) { /*master_mask = 0xFF; slave_mask = 0xFF;*/ uint32_t flags; cli_and_save(flags); outb(master_mask,MASTER_8259_PORT_2); outb(slave_mask,SLAVE_8259_PORT_2); /* outb Initial a wide range of PC hardware */ outb(ICW1, MASTER_8259_PORT); outb(ICW2_MASTER, MASTER_8259_PORT_2); outb(ICW3_MASTER, MASTER_8259_PORT_2); outb(ICW4, MASTER_8259_PORT_2); outb(ICW1, SLAVE_8259_PORT); outb(ICW2_SLAVE, SLAVE_8259_PORT_2); outb(ICW3_SLAVE, SLAVE_8259_PORT_2); outb(ICW4, SLAVE_8259_PORT_2); /*restore master irq mask*/ outb(master_mask, MASTER_8259_PORT_2); outb(slave_mask, SLAVE_8259_PORT_2); restore_flags(flags); printf("the PIC initialized!!\n"); }
/* * rtc_open * DESCRITPION: Sets the RTC to default 2Hz, and open RTC * INPUT: none * OUTPUT: none * RETURN: none * SIDE EFFECT: none */ int32_t rtc_open(){ uint32_t flags; cli_and_save(flags); // get old register A value outb(RTC_REG_A , RW_RTC_ADDR); reg = inb(RW_RTC_DATA); // set RTC to 2 Hz outb(RTC_REG_A, RW_RTC_ADDR); outb(reg | SET_INIT_RATE, RW_RTC_DATA); restore_flags(flags); // return 0 on success return RET_SUCCESS; }
/* * stdout_write * Description: write standard output * INPUTS: int32_t fd -- file descriptor void* buf -- buffer address int32_t nbytes -- number of bytes pcb_t* mypcb -- Process control block * OUTPUTS: None * RETURN: None * SIDE EFFECTS: None */ extern int32_t stdout_write(int32_t fd, const void* buf, int32_t nbytes, pcb_t* mypcb) //this function do nothing { if (fd == 1) { int i; uint32_t flag; //int8_t local[2000]; int8_t * local = (int8_t *)r_kmalloc(nbytes+1); //strcpy(local, (int8_t *)buf); memcpy(local, buf, nbytes); local[nbytes] = '\0'; //((int8_t *)buf)[nbytes-1] = '\0'; cli_and_save(flag); //printf("%s", local); if (modeX_enabled == 0) { if (check_signal((uint32_t)mypcb)){ return EPENDSIG; } for (i=0;i<nbytes;i++){ //if (local[i]!='\0') putc(local[i]); } }else { puts(local); } restore_flags(flag); mypcb->file_array[fd].file_position = nbytes; r_kfree((uint32_t)local); return nbytes; } return -1; }
/************************************************ rtc_write - change the clock frequency Probably make a function call in kernel to show that frequency can be changed *************************************************/ int32_t rtc_write(file_t* file, const uint8_t* buf, int32_t nbytes) { if(nbytes != RTC_READ_BYTES) return RET_FAILURE; uint32_t flags; cli_and_save(flags); //save all the flags and stop interrupts uint32_t frequency = *(uint32_t*)buf; if((frequency > HIGHEST_FREQ)||(frequency < LOWEST_FREQ)) //if frequency is out of bounds then return -1 { restore_flags(flags); //restore the flags even if we are returning -1 return RET_FAILURE; } //printf("inside rtc_write\n"); int rate = LOWEST_FREQ; // rate must be above 2 and not over 15 while(frequency != HIGH_16_BIT >> (rate-1)) //rate calculation formula on OS DEV { rate++; } rate--; outb(VAL_1, PORT_1); // set index to register A, disable NMI char prev = inb(PORT_2); // get initial value of register A outb(VAL_1, PORT_1); // reset index to A outb((prev & FIRST_4_BITS) | rate, PORT_2); //write only our rate to A. Note, rate is the bottom 4 bits. outb(VAL_2, PORT_1); // select register B, and disable NMI prev = inb(PORT_2); // read the current value of register B outb(VAL_2, PORT_1); // set the index again (a read will reset the index to register D) outb(prev | BIT_6, PORT_2); // write the previous value ORed with 0x40. This turns on bit 6 of register B //the offset of the RTC is IRQ1 sti(); restore_flags(flags); return RET_SUCCESS; }
/* * rtc_write * DESCRITPION: Writes a given frequency to RTC. RTC is able to generate * interrupt at rate of power of 2, driver limits the * frequency up to 1024. * INPUT: none * OUTPUT: none * RETURN: 0 on success, -1 on failure * SIDE EFFECT: none */ int32_t rtc_write(uint32_t fd, const uint32_t* buf, uint32_t nbytes){ int frequency; int power; int input_error; int temp; uint32_t flags; // get frequency in Hz frequency = *buf; /* // return if input outside range if (frequency < FREQUENCY_MIN || frequency > FREQUENCY_MAX){ return RET_ERROR; } */ // check if it is a power of 2 within range if (frequency == 0){ input_error = RESET; } else{ for (power = POWER_MIN; power <= POWER_MAX; power++){ if ((1<<power)==frequency){ input_error = RESET; temp = power; break; } else{ input_error = SET; } } } // return if input is invalid if (input_error == SET){ printf("-----------------INVALID INPUT--------------------- \n"); return RET_ERROR; } // else write to register A to change rate else{ cli_and_save(flags); // get current register A outb(RTC_REG_A, RW_RTC_ADDR); // set frequency reg = (inb(RW_RTC_DATA) & SET_FREQ_MASK) | ((RTC_FREQ_SELECT - temp)& FREQ_LOW4_MASK); // write to register A outb(RTC_REG_A, RW_RTC_ADDR); outb(reg, RW_RTC_DATA); restore_flags(flags); //printf("RTC Interrupt Rate Changed! \n"); return RET_SUCCESS; } printf("-----------------UNKNOWN FAILURE----------------------- \n"); return RET_ERROR; }