170 likes | 259 Views
Chapter 11. Input and Output. I/O Devices. Keyboard User presses A key ‘a’ ASCII is … Keyboard sends on wire, e.g. … 1 for start, 8-bits of data, 0 for stop ‘a’ is … Buffer at computer catches these bits Displays Character display works with the reverse process (sort of)
E N D
Chapter 11 Input and Output
I/O Devices • Keyboard • User presses A key ‘a’ • ASCII is … • Keyboard sends on wire, e.g. … • 1 for start, 8-bits of data, 0 for stop • ‘a’ is … • Buffer at computer catches these bits • Displays • Character display works with the reverse process (sort of) • Most displays are “bit mapped”
I/O Devices • Hard Disk • A spinning disk (4600, 5200, 7200, 10000 RPM) • 2 – 90 GB and growing FAST • Magnetic and read/write (like tape) • Both sides • Usually a stack of platters • Disk access • Electronic speeds are in the nanoseconds (10-9 sec) • Disk speeds are in the milliseconds (10-3 sec) • Why use a disk? • ? • ?
I/O Devices • Questions • How does CPU ask for a char to be printed? • Which printer? • Which display? Who’s? • When is printer ready for the next char? • When does keyboard have the next char? • What about the million times slower?
MAL I/O • putc $s0 is • # address of char is in $s0 • lb $4, ($s0) # $4 char to be printed • addi $2, $0, 11 # li + syscall is like: • syscall # jal operating_system_function • getc $s0 is • addi $2, $0, 12 # li + syscall is like: • syscall # jal operating_system_function • # returns with char read in $2
MAL I/O • Don’t use jal because • OS doesn’t trust user to provide the correct address • Want to switch into OS mode, where more thingsare allowed • Allowed by what? • OS catches syscall and uses value in $2 to determinewhat to do • OS will not allow • Users to read each other’s keyboards • Users to send infinite jobs to printers (well, actually…)
MAL I/O • How does the OS do I/O? • What instructions cause an I/O? • Could have special instructions • Hard to anticipate all possibilities • Solutions • overload load and store • Memory-mapped I/O
Memory Mapped I/O Design hardware and software to recognize certain addresses 0x00000000 Real Memory - RAM 0xffff0000 From keyboard 0xffff0008 To display 0xffff0010 • Set labels • keyboardData equ 0xffff0008 • displayData equ 0xffff0010
Memory Mapped I/O CPU MEM Keyboard Buffer0xffff0008 Display Buffer0xffff0008 • Devices on bus watch for their address • getc • operating_system_function_12: # getc char and put it in $2 • lw $2, KeyboardData • “return from syscall” • putc • operating_system_function_11: # putc char, where char is in $4 • sw $2, DisplayData • “return from syscall” • But is there a new char to read? • But is the display done with the last char?
Device Status • Need I/O device status to coordinate • Set label • KeyboardStatus equ 0xffff000c • DisplayStatus equ 0xffff0014 • Assume Status is word where MSB==1 means ready. 0x00000000 Real Memory 0xffff0000 DATA from keyboard 0xffff0008 STATUS from keyboard 0xffff000c DATA to Display 0xffff0010 STATUS from Display 0xffff0014
Device Status • getc Operating_system_function_12: # getc char and put it in $2 WaitLoop12: lw $14, KeybaordStatus bgez $14, WaitLoop12 # keep waiting if $14 non-negative lw $2, KeyboardData # same as before “return from syscall” • putc Operating_system_function_11: # putc char, where char is in $4 WaitLoop12: lw $14, DisplayStatus bgez $14, WaitLoop11 # keep waiting if $14 non-negative sw $4, DisplayData # same as before “return from syscall”
Device Status Polling (non-interrupt) I/O on HC11 • GETCHAR GETCHAR: LDAA SCSR ; status register ANDA #$20 ; rdrf bit mask BEQ GETCHAR ; loop if rdrf = 0 LDAA SCDR ; read data RTS • OUTCHAR OUTCHAR: LDAB SCSR ; load sci status register BITB #$80 ; tdre bit BEQ OUTCHAR ; loop intil tdre = 0 STAA SCDR ; write character to port RTS
Device Status • How much time is spent spinning? • A putc or getc is less than 10 instructions, or 10ns • Mechanical devices take milliseconds • Almost all time is spent spinning • Must do useful work while waiting • Periodically poll devices and send characters whenready
Polling I/O • Create • printstring – enqueue a string for printing • Printnextchar – print next char (if any) • putqueue: array[0..255] of char; • /* • ** head put queue pointer (index): points just before valid data • */ • integer hpqp; /* initialized to 0 */ • /* • ** tail put queue pointer (index): points to last valid data • */ • integer tpqp; /* initialized to 0 */ • /* • ** note: hpqp = tpqp put queue empty • */
Polling I/O putstring (string) /* ** if room available in queue, string to it. Otherwise, return “overflow”** May also print first char. */ <not shown> putnextchar() begin /* ** Is display ready? ** ** yes print a char (if any) and return ** no return */ if (DisplayStatus < 0) /* ** Return if queue is empty */
Polling I/O then begin /* ** Return if queue empty */ if (hpqp != tpqp) then begin /* ** Invariant: head ptr points just before valid data ** Update head ptr and print */ hpqp = (hpqp + 1) rem 256; DisplayData := putqueue[hpqp]; end end return() end
Polling I/O • The OS must check regularly (poll) for ready devices • Perhaps once a millisecond • If ready, then OS services device • Keyboard: transfer character and put on queue • Display: transmit character to the graphics HW • Problems: • How often to poll? • How does the OS code get run? • What happens to the user program? • Is there a better solution?