選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

45KB

Developing Your Own 32-Bit Operating System — Chapter-06: The Hardware Interface

  • Source: /library/Developing Your Own 32-Bit Operating System/source-file.pdf
  • PDF pages: 103–120
  • Pages without text: 103

The Hardware Interface

I
82 Part II ■ Architecture and General Theory As a resource manager, the operating system provides access to hardware for the programs on the system. This chapter discusses your approach to hardware interfaces and highlights some of the pitfalls to avoid. Hardware Isolation The concept of isolating the operating system (and the programmer) from directly accessing or having to control the hardware is a good idea. This concept is called hardware abstraction or hardware isolation^ it implies an additional programmatic interface layer between the hardware and the parts of the operating system that control it. You provide a common, well-defined interface to perform tasks such as moving data to and from a device, or for specific timing requirements. This well-defined interface does not require hardware-specific information for its operation from the point of view of the operating system. In theory, you therefore can port the operating system to almost any platform, as long as the target platform has similar hardware to accom- plish the required functions. You need to define logical device nomenclatures from the operating system's point of view, and physical device nomenclatures to the code that will be below this abstraction layer (which actually is controlling the hardware). The interface can be designed above or below the device driver interface. The most elegant method (and the most difficult) is when it is done below the device driver code. Not even device driver writers have to know about the hardware aspects. As good as it sounds, there are drawbacks to this idea. The two obvious drawbacks are increased code size and reduced speed. Any additional layers between the users of the hardware and the hardware itself adds to size and reduces the speed of the interface. The most obvious place this is evident is in the video arena. Adding a somewhat bulky layer between a program and the video hardware definitely slows down operation. The implementation of this hardware isolation layer also means that you must thoroughly in- vestigate all possible platforms you intend to target. It is not a good idea to try to implement a complete hardware isolation layer without having all the documentation for the target plat- forms you intend to support. You can keep your device interfaces as hardware non-specific as possible, however. Don't use any fancy nonstandard functions that might not be supported on some platforms — for example, memory-to-memory DMA transfers. The CPU The interface to the central processor unit (CPU) seems almost transparent. It executes your instructions, jumps where you tell it, and it simply runs. But there's always more than meets the eye.

Chapter 6 ■ The Hardware Interface The CPU has well-defined methods of communicating with the operating system. The most common method, aside from the instructions you give it, is the interrupt or trap. Other meth- ods may be in the form of registers that you can read to gather information on the state of the processor, or tasks that are running (or running poorly). An important consideration is how the processor stores and manipulates its data — how it is accessed in memory. Some processors store the least significant byte of a 4-byte integer at the highest memory address of the 4 bytes, and the most significant byte at the lowest address. The Intel and compatible CPUs have been referred to as “backword” in this respect because they store least-significant bytes at the lowest address, which makes more sense to me. This affects everything from the programmatic interfaces to interoperability with other systems. This often is referred to as the big-endian, little-endian problem when dealing with the exchange of infor- mation across networks or in data files. Your assembler and compilers will take care of all the details of this for you, and if you have worked with the processor for any length of time, it will be second nature. One other thing this may affect is how you manipulate the stack or access data that is on it. Timing issues also are involved with the CPU. Most 32-bit CPUs have relatively large internal instruction and data caches. These types of caches can affect the timing of certain OS-critical functions. I have learned how to enable and disable caching on the systems I work with for the purposes of debugging. I haven't run into any timing problems I can attribute to caching, but that doesn't mean that you will not experience these types of problems. An important point concerning the CPU interface is how you handle interrupts. With some CPUs, you actually can switch tasks on a hardware interrupt instead of just calling a proce- dure. This capability is handy, but it can consume a good deal of valuable bandwidth. This gets into the issue of interrupt latency, which means not being able to handle all your interrupts in a timely fashion. Switching the complete hardware and software context of a task for every interrupt simply slows you down. I've tried both methods, and I recommend interrupt proce- dures rather than interrupt tasks if at all possible. You should be sure to familiarize yourself with all aspects of the CPU by reading the manufacturer's documentation. I read many books about my target processor, but I found the most valuable, and most useful, were purchased directly from the processor manufacturer. Your interpretation of their documentation may be superior to that of those who write secondary books on these topics. The Bus Structure A bus is a collection of electrical signals that are routed through a computer system between components. Bus designs usually are based on standards and given names or numbers such as IEEE-696, ISA, EISA, PCI, or Multibus, just to name a few.

I
84 Part II ■ Architecture and General Theory The bus structure on any hardware platform usually is comprised of several buses. The most obvious to note is the bus from the CPU to the rest of the computer system. This is called the main bus, internal bus, or CPU bus. The CPU bus usually is comprised of three distinct sets of signals for most processors. The first set is the data bus, which carries the values that are read from and written to memory or I/O devices. The second is the address bus, which determines where in memory data is being read from or written to or which I/O device is being accessed. Finally, the control bus usually carries a wide variety of signals, including read and write access lines for memory and I/O, along with things like processor interrupt lines and clock signals. The CPU bus usually is connected to the main bus. On smaller systems, the main bus may be composed solely of the CPU signals; in that case, the CPU bus and the main bus are the same. The connections between buses usually are through gated devices that are turned on and off depending on who is accessing what bus. These actions are under hardware control, so you generally don't have to worry about them. The CPU bus usually is not the bus that is connected directly to the external interface devices that you must control. I refer to this bus as the interface bus. On the PC-ISA platforms, the external interface bus is called the Industry Standard Architecture, or ISA bus. There are many extensions to this bus — some proposed, and some that are available now. The interface bus may not carry all the data, address, or control lines that are found on the main or CPU bus. The PC-ISA bus, for example, is really quite crippled compared to the CPU bus. Only half the data lines make their way out to this bus (it's really a 1 6-bit bus), and not all the I/O addresses or interrupt lines can be accessed on this bus. You really don't need to know the exact hardware layouts for these buses and signals, but some of the processor documentation is fairly explicit about the effect of certain instructions con- cerning some of these signal lines, such as those dealing with interrupts. It is a good idea to familiarize yourself with the basic bus structures on your target hardware platform. Before you plan some grand interface scheme, make sure that you understand the capabilities of the plat- form you're working with, and especially the interface bus. Quite honestly, I've had to “drop back 1 0 yards and punt” a time or two. Serial I/O Many forms of serial input/output exist. The most common is the relatively low-speed, asyn- chronous serial communications (RS-232). The electronic devices that handle asynchronous communications are called UARTs (Universal Asynchronous Receiver Transmitters). UARTs actually are very forgiving devices, and they take much of the drudgery away from the pro- grammer that is implementing serial communications. Most varieties of these devices are very similar. The RS-232 device driver included with the MMURTL operating system should prove valuable to you, no matter which device you must code.

Chapter 6 ■ The Hardware Interface Other devices beside communications channels also may be controlled through UARTs. Such devices could include the keyboard or a mouse port, to name a few. Less commonly found, but still very important, are synchronous communications such as those used with X.25 (an international link and network layer standard), SDLC, or HDLC. All these synchronous communications standards have one thing in common from the operating sys- tem writer's point of view: critical timing. Unlike UART devices, USART (the added S is for synchronous) devices are very timing critical. They work with frames or packets of data. USARTs have no way, except for the hardware clock timing, to determine when one byte ends and the next byte begins. USARTs generally expect the device driver to provide these packets with very little delay. In fact, in many cases, a delay causes USARTs to abort the frame they're working on and send an error instead. You therefore must ensure that you can get out the entire frame (byte by byte) without a large delay factor involved between each byte. Buffered USARTs assist with this issue, but how your operating system implements its tasking model and its interrupt service routines (ISRs) greatly affects its capability to handle these types of devices. The issue of polling versus interrupt-driven control of communications devices crops up in documentation you read about UARTs and USARTs. The concept of polling a device means that your device driver or program always is there to continually check on the device to see when it needs attention. This procedure is performed by repeatedly reading the status registers on the UART/USART in a loop. If you intend to design a true multitasking system, I recom- mend that you forget about polling and stick with interrupts. Concentrate on the efficiency of all the ISRs on your system. Parallel I/O Parallel input/output can include devices for printer interfaces (the infamous Centronics in- terface); the IEEE-488 General Purpose Interface Bus (GPIB); and, on some systems, even the main bus may be accessible as a parallel interface of sorts (this is most common on laptops and notebook computers). Parallel buses can move data faster, simply because they are transferring information one byte or one word at a time instead of one single bit at a time in a serial fashion. These devices pro- vide interrupt-driven capabilities just like the serial devices. Quite often, parallel buses are much easier to control than serial devices because they have fewer communications options. Block-Oriented Devices Block-oriented devices can include disk drives, network frame handlers, and tape drives, to name a few. The interfaces to these devices enable large volumes (blocks) of data to be moved be- tween the devices and memory in a rapid fashion.

86 | Part II ■ Architecture and General Theory This block movement of data is accomplished in one of several ways. Direct memory access (DMA) is one method, which is discussed in detail later in this chapter. Another method is shared memory blocks — a process in which a hardware device actually takes up a portion of your physical address space, and all you do to transfer the block is write or read those addresses and then tell the device you're done. Another way in which block movement of data is accom- plished is through the use of programmed I/O, which is available on some processors such as the Intel series. Programmed I/O uses special instructions to send data to what appears to be an address, but is really a device connected to the bus. The processor may even have some form of high-speed string instructions to enable you to send blocks of data to this array of pseudo addresses. This is how the Integrated Drive Electronics (IDE) interface works on the PC-ISA systems. The major difference between these forms of block-data transfer is the consumption of CPU time (bandwidth). DMA uses the least CPU bandwidth because it is a hardware device designed to transfer data between memory and devices, or between memory and memory, during unused portions of the CPU clock cycle. You usually do not have a choice as to which method you use; the method is determined by the interface hardware (the disk or tape controller hard- ware, or the network card). The Keyboard The keyboard may or may not be a part of the hardware to control on your system. If you have a platform that communicates with its users through external terminals, you simply may have to deal with a serial device driver. On many systems, the keyboard is an integral pan of the hardware. This hardware usually is a small processor or a UART/CPU combination. If this is the case, the keyboard hardware is accessed through the I/O port (or memory address), and you need to know how to set it up and operate the device. The keyboard on many systems is preprogrammed to provide series of bytes based on some translation table within the keyboard microprocessor. Keyboard users prefer a familiar set of codes to work with, such as ASCII (American Standard Code for Information Interchange) or Unicode, which is a relatively new multibyte international standard. You are responsible for the translations required from the keyboard device if they aren't already in the desired format. Interrupts are the normal method for the keyboard device to tell you that a key has been struck; this requires an interrupt service routine. The keyboard usually can be treated as just another device on your system as far as a standardized interface, but you must realize the importance of this device. Nothing infuriates an experienced user more than an undersized type-ahead buffer or losing keystrokes. You probably can imagine the veins popping out on my forehead when I reach the huge 15-keystroke limit of MS-DOS.

Chapter 6 M The Hardware Interface Keyboard handling in a multitasking system can present some pretty interesting problems. One of these problems is how to assign and distinguish between multiple programs asking for key- strokes. Your tasking model and your programmatic interfaces determine how this is accom- plished. On the PC-ISA platform, the keyboard hardware is integrated tightly into the system. In fact, the keyboard serial device allows more than just keyboard interaction. You even can perform a CPU hardware reset through these same control ports. Quite often, devices perform more than one function on a particular platform. It's worth repeating that having the manufacturer's documentation for the platform, and even the device manufacturer's manuals (builders of the integrated circuits), is worth more than I can indicate to you. Video Like the keyboard, you may not have any video hardware at all if your user I/O is through external terminals. All the output would be via a serial port. However, most platforms have the video hardware built in or directly accessible through the interface bus. Many books have been written on the control of video hardware. This is true especially for the IBM PC-AT compatible platforms. You need to understand certain aspects of video hardware, however, because the direct hardware interaction on your platform affects thing like memory- management techniques that you must design or implement. The two basic forms of video display are character-based and bit-mapped graphics. Each of these displays requires a completely different approach to how you interface video with your operating system. In most cases, you have direct access to video memory somewhere in the array of physical addresses that your CPU can reach. In character-based systems, this video memory contains character codes (ASCII, for example) that the video hardware translates into individual scan lines on-screen to form the characters. This method consumes the least amount of your address space. One byte per character and maybe one byte for the character's color or attribute are required. On an 80-column-by-25- line display, this method consumes only 4000 bytes. Bit-mapped graphics-based systems are much more complicated to deal with, and can con- sume a much larger area of your address space. Graphics systems must have an address for each bit or pixel (picture element) of information you want to manipulate or display. In a mono- chrome system with a decent resolution, this area can be 600 or more bits across and as many as 500 bits vertically: 600 x 500 + 8 (size of a byte in bits) = 37,500 bytes of memory space A very common resolution on many systems is 1280x1024. If you want 1 6 colors for each bit, this would require three additional arrays to provide the independent color information. These arrays could consume a vast amount of memory. Video

I 88 Part II ■ Architecture and General Theory hardware manufacturers realize this problem. Manufacturers provide methods to allow these arrays to occupy the same physical address space, and they give you a way to switch between the arrays. This capability is known as planar pixel access. Each bit array is on its own plane. Another method is to make each nibble of a byte represent the four color bits for each dis- played bit on-screen. Then video memory is broken into four or more sections, and you can switch between the sections. This capability is known as packed pixel access. Even though you can access each of these memory sections in parallel, it is still a vast amount of memory to ac- cess. A 256-color system, for example, contains 16 planes at 37,500 bytes (using the 600x500 size sample). That equates to 600,000 bytes. Only one plane of the total memory consumes your address space, because the video interface cards have RAM that they switch in and out of your address space. The efficiency of your video routines therefore has a large effect on the apparent system speed as seen by the user. These methods of displaying video information require you to allocate an array of OS-man- aged memory that is for the video display subsystem. The video hardware usually must be programmed to tell it where this memory is located. How much memory you require is deter- mined by what methods your video hardware uses. Other aspects of the video subsystem also require your attention. Two such aspects to consider are cursor positioning, which is hardware-controlled on character-based systems, and timing, or when you write to the video display area. In this age of graphics-based systems and graphical user interfaces, you need to take graphics into consideration even if you build a character-based system first. Your graphics implementa- tion might have an effect on your memory management design or even your tasking model. I considered future video and graphics requirements with MMURTL. I even cheated a little and left the video subsystem set up the way the boot ROM left it because it suited my purposes. I did, however, have to research hardware cursor control, and I also allocated memory for large graphics arrays during initialization. See Chapter 26, “Video Code,” for descriptions of each of the calls I designed for the video interface. I was interested in character-based, multiple, non- overlapping video users. Your requirements probably are different. The concept of a message-based operating system plays well into event-driven program con- trol (such as a windowing system). I took this into consideration also. I recommend that you purchase a book that details the video hardware that you intend to con- trol long before you implement your memory management, interprocess communications, and tasking model. One thing I should mention is that many video subsystems may provide video code in ROM to control their hardware. In many cases, this code is of little use to you after the system is booted. In some cases, the video ROM's only purpose is to test and set up the video hardware during the testing and initialization phases of the boot process. Video-handling code even may be provided in the form of a BIOS ROM (Basic Input/Output System). This code can be use- less if it does not execute properly in your system (16-bit code in a 32-bit system, for example).

Chapter 6 ■ The Hardware Interface Make certain that the video documentation you acquire documents hardware access and not simply access to the code found in ROM. Direct Memory Access (DMA) You find DMA hardware on almost all platforms you work with, except maybe an embedded system board. DMA devices have several control lines that connect to the CPU and to the devices that use it. These control lines provide the necessary “handshakes” between the device and the DMA hardware. Programmers that write device drivers have often faced the chore of learning all the intricacies of DMA hardware. In a multitasking system that may have several DMA users, the operating system must ensure harmony between these users. If the programmers follow the rules for programming the DMA hardware to the letter, you will have no problems, but this means that the programmers must be well versed on DMA hardware-control requirements. A better plan is to provide users with a programmatic interface to use the DMA hardware, which takes care of the synchronization and details of DMA programming. DMA hardware also requires that the programmer know the physical addresses with which he or she is working. Direct memory access is a hardware device that operates outside the virtual address translations that may be taking place within the paging hardware of the processor or external paged memory management unit. I'll show you what I provided for users of DMA. With minimal changes, you can use this code on almost any system, taking into account the differences in control registers and commands on the target system's DMA hardware. I provided a method to allocate memory that returns the physical address programmers require, which I touched on in Chapter 5, “Memory Man- agement.” I also gave users high level calls to set up the DMA hardware for a move, and to query the status of the move. The DMA hardware calls are SetUpDMA( ) and GetDMACount( ). The code for these calls follows: .DATA .INCLUDE MOSEDF.INC .CODE The code is larger than it could be, because I have expanded out each channel instead of using a simple table for the registers. Optimize it as you please. There really is no data segment for DMA, but the standard include file MOSEDF.INC is used for error codes that may be returned to the caller. With 8-bit DMA, the lower word (bits 15 through 0) is placed into the address registers of the DMA, and the page register is the next most significant byte (bits 23 through 16). With word, DMA moves (channels 5 through 7), address bits 16 through 1 are placed in the address reg- isters, and 23 through 17 are placed in the page register. Bit 16 is ignored by the page register. The page registers determine which 64K or 128K section of memory is being accessed.

H Part II ■ Architecture and General Theory There are two 4-channel DMA devices. One of the channels from the second device is fed into a channel on the first device. This setup is called a cascaded device. The following equates are the register addresses for these two devices on ISA hardware: ; DMA 1 Port DMA1 0Add DMA10Cnt DMA11Add DMA11Cnt DMA1 2Add DMA12Cnt DMA1 3Add DMA13Cnt DMAIStatCmd DMAIRqReg DMA1 RCmdWbm DMAIMode DMA1FF DMA1 Clear DMAIClrMode DMAIMskBts DMA Equates addresses EQU 00h EQU 01 h 02h 03h 04h 05h 06h EQU EQU EQU EQU EQU EQU 07h EQU 08h EQU 09h EQU 0Ah EQU 0Bh EQU 0Ch EQU 0Dh EQU 0Eh EQU 0Fh for DMA and PAGE registers ========= and page registers ;Ch 0 Address ;Ch 0 Word Count ;Ch 1 Address ;Ch 1 Word Count ;Ch 2 Address ;Ch 2 Word Count ;Ch 3 Address ;Ch 3 Word Count ;Read Status/Write Command ; Read/Write DMA Rq Register ;Read Command/Write Single bit mask ;Read/Write Mode register ;Writing this address clears byte ptr flip flop ;Write causes MASTER Clear (Read from Temp Reg) ;Rd clears mode reg count/Wr Clr ALL mask bits ;Read/Write DMA Rq Mask Register DMA 2 Port addresses EQU EQU EQU EQU EQU EQU EQU EQU DMA20Add DMA20Cnt DMA21Add DMA21Cnt DMA22Add DMA22Cnt DMA23Add DMA23Cnt DMA2StatCmd EQU DMA2RqReg EQU DMA2RCmdWbm EQU DMA2Mode EQU DMA2FF EQU DMA2Clear EQU DMA2ClrMode EQU DMA2MskBtS EQU 0C0h ;Ch 0 Address 0C2h ;Ch 0 Word Count 0C4h ;Ch 1 Address 0C6h ;Ch 1 Word Count 0C8h ;Ch 2 Address 0CAh ;Ch 2 Word Count 0CCh ;Ch 3 Address 0CEh ;Ch 3 Word Count 0D0h ;Read Status/Write Command 0D2h ; Read/Write DMA Rq Register 0D4h ;Read Command/Write Single bit mask 0D6h ; Read/Write Mode register 0D8h ;Writing this address clears byte ptr flip flop 0DAh ;Write causes MASTER Clear (Read from Temp Reg) 0DCh ;Rd clears mode reg count/Wr Clr ALL mask bits 0DEh ; Read/Write DMA Rq Mask Register ;DMA Page register by DRQ/DACK number DMAPage0 DMAPagel DMAPage2 DMAPage3 DMAPage5 DMAPage6 DMAPage7 EQU 87h EQU 83h EQU 81 h EQU 82h EQU 8Bh EQU 89h EQU 8Ah ;DMA DACK0 Page register ; DACK1 (etc. etc. etc.) The following internal call sets up the initial DMA channel values for both chips to most prob- able use. This includes the cascade mode for generic channel 4, which is DMA channel 0 on DMA chip 2. This is called one time during initialization of the operating system:

Chapter 6 ■ The Hardware Interface H PUBLIC InitDMA: MOV AL, 04 OUT DMAIStatCmd, AL OUT DMA2StatCmd, AL XOR AL, AL OUT DMA1 Clear, AL OUT DMA2Clear, AL XOR AL, AL OUT DMAIStatCmd, AL OUT DMA2StatCmd, AL AL MOV AL, 40h OUT DMAIMode, MOV AL, 0C0h OUT DMA2M0de, AL MOV AL, 41 h OUT DMAIMode, AL OUT DMA2M0de, AL MOV AL, 42h OUT DMAIMode, AL OUT DMA2M0de, AL MOV AL, 43h OUT DMAIMode, AL OUT DMA2M0de, AL XOR AL.AL OUT DMAIClrMode, AL OUT DMA2ClrMode, AL RETN ;Master disable ; MASTER CLEAR (same as hardware reset) ;A11 commands set to default (0) CH 0 DMA 1 CH 0 DMA 2 (Cascade Mode) CH 1 DMA 1 & 2 CH 2 DMA 1 & 2 CH 3 DMA 1 & 2 ; Enable ALL DMA 1 Channels ; Enable ALL DMA 2 Channels The PUBLIC call DMASetUp( ) sets up a single DMA channel for the caller. DMA is crippled be- cause it cannot move data across 64K physical boundaries for a byte-oriented move, or 128K boundaries for a word move. I left it up to the caller to know whether their physical addresses violate this rule. If they do, the segment is wrapped around and data is moved into the lower part of the current 64K segment (not into the next segment, as you might assume). The caller sets the type of DMA operation (In, Out, or Verify). For channels 5, 6, and 7, the address and count must be divided by 2 for the DMA hardware. I do this for the callers, so they always specify byte count for the setup call, even on word moves. The PUBLIC call DMASetUpO follows: DmaSetUp(dPhyMem, sdMem, dChannel, dType, dMode) EBP+ 28 24 20 16 12 dPhyMem is physical memory address sdMem is nBytes to move (STILL bytes for word xfers, we do math) dChannel (0,1,2,3,5,6,7) dType - 0 = Verify, 1 = In (Write Mem), 2 = Out (Read memory) dMode - 0 Demand Mode, 1 Single Cycle, (Floppy Disk I/O uses 1) 2 Block, 3 Cascade

H Part II ■ Architecture and General Theory PUBLIC _DMASetUp: PUSH EBP MOV EBP, ESP MOV EAX, [EBP+12] CMP EAX, 04 JB DMAModeOK MOV EAX, ErcDMAMode JMP DMAEnd DMAModeOK: SHL EAX, 6 MOV BL, AL MOV EAX, [EBP+16] AND BL, 0C0h CMP EAX, 0 JE DMASelect CMP EAX, 1 JE DMAWrite DMARead: OR BL, JMP DMASelect DMAWrite: OR BL, 00000100b DMASelect: MOV EAX, [EBP+20] CMP EAX, 0 JE DMA0 CMP EAX, 1 JE DMA1 CMP EAX, 2 JE DMA2 CMP EAX, 3 JE DMA3 CMP EAX, 5 JE DMA5 CMP EAX, 6 JE DMA6 CMP EAX, 7 JE DMA7 MOV EAX, ErcDMAChannel JMP DMAEnd dMode Mode must be < 4 Move Mode bits to 6 and 7 Put it in BL get dType Set to Verify by default (low bits 0) Check fType (Verify?) Yes In? (Write) Yes (if no then fall through to Read) OR read command to BL (OUT) ; OR write command to BL (IN) ;Jump table for channel selection DMA0: CLI MOV AL, 00000100b OUT DMAIRCmdWbm, AL MOV AL, 00000000b OR AL, BL OUT DMAIMode, AL OUT DMA1FF, AL MOV EAX, [EBP+28] OUT DMA10Add, AL SHR EAX, 8 OUT DMA10Add, AL SHR EAX, 8 OUT DMAPage0, AL MOV EAX, [EBP+24] channel 0 Set Mask for DRQ CH0 (CH is last 2 bits) OR with MODE Clear FlipFLop (Val in AL irrelevent) dPhyMem Lo byte address Hi Byte Highest byte (to page register)

Chapter 6 M The Hardware Interface H DEC EAX OUT DMA10Cnt, AL SHR EAX, 8 OUT DMA10Cnt, AL MOV AL, 00000000b ; channel 0 Clear Mask for DRQ OUT DMAIRcmdWbm, AL ST I XOR EAX, EAX JMP DMAEnd CLI MOV AL, 00000101b ; channel 1 Set Mask for DRQ OUT DMA1 RCmdWbm , AL MOV AL, 00000001b ; CH1 OR AL, BL ; OR with MODE/TYPE OUT DMAIMode, AL OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) MOV EAX, [EBP+28] ; dPhyMem OUT DMAHAdd, AL ; Lo byte address SHR EAX, 8 OUT DMAHAdd, AL ; Hi Byte SHR EAX, 8 OUT DMAPagel, AL ; Highest byte (to page register) MOV EAX, [EBP+24] ; sdMem DEC EAX OUT DMA11Cnt, AL SHR EAX, 8 OUT DMA11Cnt, AL MOV AL, 00000001b ; channel 1 Clear Mask for DRQ OUT DMAIRcmdWbm, AL STI XOR EAX, EAX JMP DMAEnd CLI MOV AL, 00000110b ; channel 2 Set Mask for DRQ OUT DMAIRCmdWbm, AL MOV AL, 00000010b ; CH2 OR AL, BL ; OR with MODE OUT DMAIMode, AL OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) MOV EAX, [EBP+28] ; dPhyMem OUT DMA12Add, AL ; Lo byte address SHR EAX, 8 OUT DMA12Add, AL ; Hi Byte SHR EAX, 8 OUT DMAPage2, AL ; Highest byte (to page register) MOV EAX, [EBP+24] ; sdMem DEC EAX OUT DMA12Cnt, AL SHR EAX, 8 OUT DMA12Cnt, AL MOV AL, 00000010b ; channel 2 Clear Mask for DRQ OUT DMAIRcmdWbm, AL STI XOR EAX, EAX JMP DMAEnd

94] Part II ■ Architecture and General Theory DMA3: CLI MOV AL, 00000111b ; channel 3 Set Mask for DRQ OUT DMAIRCmdWbm, AL MOV AL, 00000011b ; CH3 OR AL, BL ; OR with MODE OUT DMAIMode, AL OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) MOV EAX, [EBP+28] ; dPhyMem OUT DMA13Add, AL ; Lo byte address SHR EAX, 8 OUT DMA13Add, AL ; Hi Byte SHR EAX, 8 OUT DMAPage3, AL ; Highest byte (to page register) MOV EAX, [EBP+24] ; sdMem DEC EAX OUT DMA13Cnt, AL SHR EAX, 8 OUT DMA13Cnt, AL MOV AL, 00000011b ; channel 3 Clear Mask for DRQ OUT DMAIRcmdWbm, AL ST I XOR EAX, EAX JMP DMAEnd ;NOTE: DMA channels 5-7 are on DMA2 and numbered 1-3 for chip select purposes CLI MOV OUT MOV OR OUT OUT MOV MOV AND SHR OUT SHR OUT MOV SHR OUT MOV SHR DEC OUT SHR OUT MOV OUT STI XOR JMP AL, 00000101b DMA2RCmdWbm, AL AL, 00000001b AL, BL DMA2Mode, AL DMA2FF, AL EAX, [EBP+28] EBX, EAX EAX, 0FFFFh EAX, 1 DMA21Add, AL EAX, 8 DMA21Add, AL EAX, EBX EAX, 15 DMAPage5, AL EAX, [EBP+24] EAX, 1 EAX DMA21Cnt, AL EAX, 8 DMA21Cnt, AL AL, 00000001b DMA2RcmdWbm, AL EAX, EAX DMAEnd channel 1 DMA2 Set Mask for DRQ CH1 on DMA 2 OR with MODE Clear FlipFLop (Val in AL irrelevent) dPhyMem Save EBX for page Rid of all but lower 16 DIV by 2 for WORD Xfer (bits 16-1) Lo byte address Hi Byte We only need 23-17 for the page Highest byte (to page register) sdMem DIV by 2 for WORD Xfer One less word channel 1 Clear Mask for DRQ

Chapter 6 I The Hardware Interface E CLI MOV AL, 00000110b ; channel 2 Set Mask for DRQ OUT DMA2RCmdWbm , AL MOV AL, 00000010b ; CH2 on DMA 2 OR AL, BL ; OR with MODE OUT DMA2Mode, AL OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent) MOV EAX, [EBP+28] ; dPhyMem MOV EBX, EAX AND EAX, 0FFFFh ; Rid of all but lower 16 SHR EAX, 1 ; DIV by 2 for WORD Xfer OUT DMA22Add, AL ; Lo byte address SHR EAX, 8 OUT DMA22Add, AL ; Hi Byte MOV EAX, EBX SHR EAX, 15 OUT DMAPage6, AL ; Highest byte (to page register) MOV EAX, [EBP+24] ; sdMem SHR EAX, 1 ; DIV by 2 for WORD Xfer DEC EAX OUT DMA22Cnt, AL SHR EAX, 8 OUT DMA22Cnt, AL MOV AL, 00000010b ; channel 2 Clear Mask for DRQ OUT DMA2RcmdWbm, AL ST I XOR EAX, EAX JMP DMAEnd CLI MOV AL, 00000111b ; channel 3 Set Mask for DRQ OUT DMA2RCmdWbm, AL MOV AL, 00000011b ; CH3 on DMA 2 OR AL, BL ; OR with MODE OUT DMA2Mode, AL OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent) MOV EAX, [EBP+28] ; dPhyMem MOV EBX, EAX AND EAX, 0FFFFh ; Rid of all but lower 16 SHR EAX, 1 ; DIV by 2 for WORD Xfer OUT DMA23Add, AL ; Lo byte address SHR EAX, 8 OUT DMA23Add, AL ; Hi Byte MOV EAX, EBX SHR EAX, 15 OUT DMAPage6, AL ; Highest byte (to page register) MOV EAX, [EBP+24] ; sdMem SHR EAX, 1 ; DIV by 2 for WORD Xfer DEC EAX OUT DMA23Cnt, AL SHR EAX, 8 OUT DMA23Cnt, AL MOV AL, 00000011b ; channel 3 Clear Mask for DRQ OUT DMA2RcmdWbm, AL STI XOR EAX, EAX

%] Part II ■ Architecture and General Theory DMAEnd: MOV ESP, EBP POP EBP RETF 20 20 bytes of junk to dump After the DMA call has been made, the device you are transferring data to or from usually in- terrupts you to tell you it's done. In cases where you always move a fixed size block such as a floppy disk, you can assume that the block was moved if the device status says everything went smoothly (there was no error from the floppy controller, for example). On some devices, you may not always be moving a fixed-size block. In this case, you have to check the DMA control- ler to see how many bytes or words were moved when you received the interrupt. The call GetDMACount( ) returns the number of bytes or words left in the DMA count register for the channel specified. For channels 5 through 7, this is the number of words. For channels 0 through 3, this is bytes. You should note that this value reads one less byte or word than is really left in the channel. This occurs because 0 = 1 for setup purposes. To move 64K, you actually set the channel byte count to 65,535: GetDMACount(dChannel, pwCountRet) EBP+ 16 12 dChannel (0,1,2,3,5,6,7) pwCountRet is a pointer to a Word (2 byte unsigned value) where the count will be returned. The count is number of WORDS-1 for channels 5-7 and BYTES-1 for channels 0-3. PUBLIC _GetDMACount: PUSH EBP ; MOV EBP, ESP ; MOV EAX, [EBP+16] MOV ESI, [EBP+12] DMACSelect: CMP EAX, 0 JNE SHORT DMAC1 MOV DX, DMA10Cnt JMP SHORT DMACDoIt ;Channel :Return address for count DMAC1 DMAC2 : DMAC3 : CMP EAX, 1 JNE SHORT DMAC2 MOV DX, DMA11Cnt JMP SHORT DMACDoIt CMP EAX, 2 JNE SHORT DMAC3 MOV DX, DMA12Cnt JMP SHORT DMACDoIt CMP EAX, 3 JNE SHORT DMAC5 MOV DX, DMA13Cnt JMP SHORT DMACDoIt

Chapter 6 ■ The Hardware Interface H DMAC5 : DMAC6 : CMP EAX, 5 JNE SHORT DMAC6 MOV DX, DMA21Cnt JMP SHORT DMACDoIt CMP EAX, 6 JNE SHORT DMAC7 MOV DX, DMA22Cnt JMP SHORT DMACDoIt MOV DX, DMA23Cnt CMP EAX, 7 JE SHORT DMACDoIt MOV EAX, ErcDMAChannel MOV ESP, EBP POP EBP RETF 8 DMACDoIt: CLI IN AL.DX MOV CL,AL IN AL.DX MOV CH.AL STI MOV WORD PTR [ESI], CX XOR EAX, EAX MOV ESP, EBP POP EBP RETF 8 No such channel! 20 bytes of junk to dump CX has words/bytes left in DMA 8 bytes to dump from the stack Timers A hardware timer is a very important piece of any operating system. Almost everything you do is based around an interrupt from a hardware timer. A hardware timer is basically a clock or stopwatch-like device that you can program to inter- rupt you once or at set intervals. This interval or time period can range from microseconds to seconds, or even hours in some cases. Internally, hardware timers have a counting device (a register) that is usually decremented based on a system-wide clock signal. You generally can set a divisor value to regulate how fast this register is decremented to zero, which determines the interrupt interval. Quite often, these devices enable you to read this register to obtain the count- down value at any time. Some platforms may provide multiple hardware timers that you can access, program, and read as required. One or more of these timers may be dedicated to hardware functions on the system board, and not available to the operating system interrupt mechanisms directly. The operating system may be responsible for programming these dedicated timers, however, or at least for making sure that the system doesn't interfere with the timers after they are set up by ROM initialization prior to boot time.

I
98 Part II ■ Architecture and General Theory If you have timers that perform system functions for the hardware, they probably are initial- ized at boot time and you can forget them. These timers may be for things like DMA refresh or some form of external bus synchronization. The Priority Interrupt Controller Unit (PICU) The PICU is a very common device found on most platforms. Usually, the processor has one or two electrical signal lines that external hardware uses to indicate an interrupt. A hardware interrupt is a signal from a device that tells the CPU (the operating system) that it needs servic- ing of some sort. As you can imagine (or have realized), many devices interrupt the processor. Therefore, some form of multiplexing must take place on the CPU interrupt signal line. The device that handles all the devices that may interrupt, and then eventually feeds one signal to the CPU, is the PICU. A PICU has several lines that look like the CPU interrupt line to the devices, and also has the logic to select one of these incoming signals to actually interrupt the CPU. In the process of an interrupt, the CPU must know which device is interrupting it so that it can dispatch the proper interrupt service routine (ISR). This ISR usually is performed by the CPU, which places a value on the data lines when the CPU acknowledges the interrupt. The PICU takes care of this for you, but you generally must set values to indicate what will be placed on the bus. Your job is to know how to program the PICU. This is not very complicated, but it is critical that it's done correctly. There are instructions to tell the PICU when your ISR is finished and interrupts can begin again, ways to tell the PICU to block a single interrupt, and ways tell the PICU how to prioritize all the interrupt lines that it services. All this information is very specific to the PICU that your platform uses. You will need the hardware manual for code examples.

Powered by TurnKey Linux.