CS计算机代考程序代写 javascript Java gui flex cache CPSC 213 Introduction to Computer Systems

CPSC 213 Introduction to Computer Systems
Winter Session 2020, Term 2
Unit 2a – Mar 17
I/O Devices, Interrupts and DMA

Overview
‣ Reading in Text
• 8.1, 8.2.1, 8.5.1-8.5.3
‣ Learning Goals
• Explain what PIO is, why it exists, what processor originates it, and how it is used
• Explain what DMA is, why it exists, what it does, and what processor originates it
• Explain what an interrupt is, why it exists, what it does, and what processor originates it
• Compare PIO and DMA by identifying when each can be used and when each should be used
• Explain the relationship between polling, PIO and interrupts
• Explain the conditions that make polling acceptable or not
• Explain what happens when an interrupt occurs at the hardware level
• Explain what is means for an operation such as a disk read to be asynchronous and give examples of code that works when an operation is synchronous but does not work with it is asynchronous
• Write event-driven programs in C using function pointers
• Describe why event-driven programs may be harder to write, read, and debug
2

A Computer System Abstraction
Address
CPU Data Memory

A Computer System Abstraction
Commands
Address
I/O Signals CPU Data Memory Data

Looking Beyond the CPU and Memory
Memory Bus
CPU
The Processors
‣ Memory Bus
• data/control path connecting CPU,
Main Memory, and I/O Bus
• also called the Front Side Bus
I/O Bus
Memory
I/O Controllers
I/O Devices
‣ I/O Bus
• data/control path connecting Memory
Bus and I/O Controllers • e.g., PCI
‣ I/O Controller
• a processor running software (firmware)
• connects I/O Device to I/O Bus • e.g., SCSI, SATA, Ethernet, …
‣ I/O Device
• I/O mechanism that generates or
consumes data
• e.g., disk, radio, keyboard, mouse, …
5

Talking to an I/O Controller
read 0x80000000
0x80000000 – 0x800000ff
read 0x1000
… 0x80000400 – 0x800004ff
addresses
0x0 – 0x7fffffff
Real Memory
I/O Memory
‣ Programmed I/O (PIO)
• CPU transfers a word at a time between CPU and I/O controller
• typically use standard load/store instructions, but to I/O-mapped memory
‣ I/O-Mapped Memory
• memory addresses outside of main memory
• used to name I/O controllers (usually configured at boot time)
• loads and stores are translated into I/O-bus messages to controller
‣ Example
• to read/write to controller at address 0x80000000
ld $0x80000000, r0
st r1 (r0) # write the value of r1 to the device
ld (r0), r1 # read a word from device into r1
6

Limitations of PIO
‣ Reading or writing large amounts of data slows CPU • requires CPU to transfer one word at a time
• controller/device is much slower than CPU
• and so, CPU runs at controller/device speed, mostly waiting for controller
‣ I/O Controller cannot initiate communication
• sometimes the CPU asks for data
• but, sometimes controller receives data for the CPU, without CPU asking – e.g., mouse click or network packet reception (everything is like this really as we will see)
• how does controller notify CPU that it has data the CPU should want?
‣ One idea…
• what is it? ___________________________________________________ • what are drawbacks? _________________________________________ • when is it okay? ______________________________________________
7

Polling and I/O Memory
CPU
I/O Controller
80000100
80000104
0 1
07
ready value
800000100
800000104
3 2
ready value v
800000100
800000104
07
5
int pollDeviceForValue() {
volatile int *ready = 0x80000100;
volatile int *value = 0x80000104;
int v;
void readyValueForCPUPoll(int v) {
volatile int *ready = 0x80000100;
volatile int *value = 0x80000104;
while(*ready != 0) {}; *value = v; 2
while(*ready == 0) {}; v = *value; 4 *ready = 0;
return v;
1
}
Reading (or writing) I/O Memory IS SLOW
CPU -> I/O Device: give me value at address X I/O Device -> CPU: here is value
Polling is Okay If poll has low overhead or if high-probability of “hit”. 8
*ready = 1; }
3
readyValueForCPUPoll (7);

Question 2a.1
‣ In a particular computer with a 32-bit CPU, addresses 0xc0000000 – 0xffffffff are reserved for I/O memory.
‣ What is the maximum amount of main memory (RAM) the computer can use?
A. 1 GB (230 bytes) B. 2 GB
C. 3 GB
D. 4 GB
E. Cannot determine from the given information
9

Key Observation
The Processors
‣ CPU and I/O Controller are independent processors • they should be permitted to work in parallel
• either should be able to initiate data transfer to/from memory
• either should be able to signal the other to get the other’s attention
10

Autonomous Controller Operation
PIO:
data transfer
CPU <-> Controller initiated by CPU
DMA:
data transfer Controller <-> Memory initiated by Controller
‣ Direct Memory Access (DMA)
• controller can send/read data from/to any main memory address • the CPU is oblivious to these transfers
• DMA addresses and sizes are programmed by CPU using PIO
11

Transferring Data: PIO vs DMA
‣ PIO is simpler to setup – read/write a fixed memory address
• DMA requires setting up the DMA controller, initiating a transfer, waiting for completion
‣ PIO is more flexible – CPU in control of every transfer • DMA may only support certain kinds of transfers (e.g. contiguous
memory)
‣ PIO is simpler to implement
• DMA requires bus coordination (to prevent CPU and DMA from using
simultaneously), and CPU cache coordination (313 topic)
‣ DMA is much faster for bulk data
• PIO occupies the CPU during transfers – DMA frees up the CPU
12

Autonomous Controller Operation
PIO:
data transfer
CPU <-> Controller initiated by CPU
DMA:
data transfer Controller <-> Memory initiated by Controller
Interrupt:
control transfer controller -> CPU
‣ Direct Memory Access (DMA)
• controller can send/read data from/to any main memory address • the CPU is oblivious to these transfers
• DMA addresses and sizes are programmed by CPU using PIO
‣ CPU Interrupts
• controller can signal the CPU
• CPU checks for interrupts on every cycle (its like a really fast, clock-speed poll)
• CPU jumps to controller’s Interrupt Service Routine if it is interrupting 13

Adding Interrupts to Simple CPU
‣ New special-purpose CPU registers
• isDeviceInterrupting set by I/O Controller to signal interrupt
• interruptControllerID set by I/O Controller to identify interrupting device • interruptVectorBase interrupt-handler jump table, initialized a boot time
‣ Modified fetch-execute cycle
while(true) {
if(isDeviceInterrupting) {
r[5] ← r[5] – 4; m[r[5]] ← r[6];
r[6] ← pc;
pc ← interruptVectorBase[interruptControllerID];
}
fetch();
execute();
}
RTI: Return from Interrupt Instruction
t ← r[6];
r[6] ← m[r[5]]; r[5] ← r[5] + 4;
isDeviceInterrupting ← 0;
pc ← t;
14

Interrupt Control Flow on CPU
Current Program
















1. CPU is running a program
2. Controller #0 interrupts
3. CPU detects interrupt 4. CPU jumps to its ISR 5. ISR returns to program
ISR – Controller #0



rti
ISR – Controller #1



rti
ISR – Controller #2



rti
ISR – Controller #3



rti
15
interruptVectorBase Register

Architectural View of Interrupts
CPU
isDeviceInterrupting interruptController ID
I/O Controller 3
I/O Controller 7
myId
010 730
myId
3
7
while(true) {
if(isDeviceInterrupting) {
r[5] ← r[5] – 4; m[r[5]] ← r[6];
r[6] ← pc;
pc ← interruptVectorBase[interruptControllerID];
isDeviceInterrupting ← 0;
}
fetch();
execute();
}
Polling on CPU register instead of I/O Memory: turning bad polling into good polling 16

Monitoring Events: Polling vs Interrupts
‣ Polling is simpler to implement
‣ Polling is useful with periodic code
• For example: a game runs at 60Hz, and polls input on every frame
‣ Polling is predictable
• Polling happens at fixed points in time in a program
‣ Interrupts are more reliable
• Polling at the wrong time might lose an event – need special handling to
avoid this
• Polling too fast is inefficient – polling too slow increases latency or drops events
‣ Interrupts are more efficient
• CPU can “sleep” or perform other tasks while waiting for an interrupt
17

Question 2a.2
‣ A touchscreen needs to notify the CPU that the user touched the screen.

Which option is best suited for this operation?
A. CPU uses PIO to periodically request the touch status
B. Touchscreen controller uses PIO to notify the CPU
C. Touchscreen controller issues a DMA request to change a predefined address in memory; CPU periodically checks that memory address for a new touch
D. Touchscreen controller interrupts the CPU; CPU runs a pre- determined interrupt handler
E. Touchscreen controller changes a pre-determined register in the CPU when a touch occurs
18

Question 2a.3
‣ The CPU decides to turn on the CAPS LOCK indicator on the keyboard.

Which option is better suited for this operation?
A. CPU changes a pre-determined register associated with the keyboard
B. CPU changes a pre-determined memory address (in main memory) associated with the keyboard
C. CPU issues a PIO request to a memory address associated with the keyboard
D. CPU issues a DMA request to the keyboard controller
E. CPU halts until the user presses the CAPS LOCK key
19

Programming with I/O

Disk Read Timeline
CPU I/O Controller 1. PIO to request read

do other things …
2. PIO Received, start read

wait for read to complete …
3. Read completes
4. Transfer data to memory (DMA)
5. Interrupt CPU
6. Interrupt Received Call readComplete
A disk stores blocks of data. Each block has a number. CPU can read or write.
21

Disk Read Timeline
1 PIOtorequestread
3
DMA data to memory
CPU
Memory
I/O Controllers
I/O Devices
4
Interrupt CPU
CPU
Disk Controller
Time
PIO
Idle or do something else
Read block
2
Transfer data from disk into controller memory
Get block from disk, DMA transfer to Memory, Interrupt CPU
22

The Power of the Sequence
‣ Consider a program that reads data from a disk
• you can sort of think of the read has having three parts: 1. figure out what data you want
2. get the data
3. do something with the data you got
• these steps must happen in this order • we think of these steps as a sequence
‣ For Example …
int sumDiskData(blockNum, numBytes) {
char buf[numBytes];
int sum = 0;
diskRead(buf, blockNum, numBytes);
for(int i=0; iop = DISK_OP_READ;
dc->buf = buf;
dc->blockNum = blockNum;
dc->numBytes = numBytes;
}
29

Did We Really Solve The Problem?
‣ We wanted to do this
int sumDiskData(blockNum, numBytes) {
char buf[numBytes];
int sum = 0;
diskRead(buf, blockNum, numBytes);
for (int i=0; i