|  |  | 
|  | EDU device | 
|  | ========== | 
|  |  | 
|  | Copyright (c) 2014-2015 Jiri Slaby | 
|  |  | 
|  | This document is licensed under the GPLv2 (or later). | 
|  |  | 
|  | This is an educational device for writing (kernel) drivers. Its original | 
|  | intention was to support the Linux kernel lectures taught at the Masaryk | 
|  | University. Students are given this virtual device and are expected to write a | 
|  | driver with I/Os, IRQs, DMAs and such. | 
|  |  | 
|  | The devices behaves very similar to the PCI bridge present in the COMBO6 cards | 
|  | developed under the Liberouter wings. Both PCI device ID and PCI space is | 
|  | inherited from that device. | 
|  |  | 
|  | Command line switches: | 
|  | -device edu[,dma_mask=mask] | 
|  |  | 
|  | dma_mask makes the virtual device work with DMA addresses with the given | 
|  | mask. For educational purposes, the device supports only 28 bits (256 MiB) | 
|  | by default. Students shall set dma_mask for the device in the OS driver | 
|  | properly. | 
|  |  | 
|  | PCI specs | 
|  | --------- | 
|  |  | 
|  | PCI ID: 1234:11e8 | 
|  |  | 
|  | PCI Region 0: | 
|  | I/O memory, 1 MB in size. Users are supposed to communicate with the card | 
|  | through this memory. | 
|  |  | 
|  | MMIO area spec | 
|  | -------------- | 
|  |  | 
|  | Only size == 4 accesses are allowed for addresses < 0x80. size == 4 or | 
|  | size == 8 for the rest. | 
|  |  | 
|  | 0x00 (RO) : identification (0xRRrr00edu) | 
|  | RR -- major version | 
|  | rr -- minor version | 
|  |  | 
|  | 0x04 (RW) : card liveness check | 
|  | It is a simple value inversion (~ C operator). | 
|  |  | 
|  | 0x08 (RW) : factorial computation | 
|  | The stored value is taken and factorial of it is put back here. | 
|  | This happens only after factorial bit in the status register (0x20 | 
|  | below) is cleared. | 
|  |  | 
|  | 0x20 (RW) : status register, bitwise OR | 
|  | 0x01 -- computing factorial (RO) | 
|  | 0x80 -- raise interrupt 0x01 after finishing factorial computation | 
|  |  | 
|  | 0x24 (RO) : interrupt status register | 
|  | It contains values which raised the interrupt (see interrupt raise | 
|  | register below). | 
|  |  | 
|  | 0x60 (WO) : interrupt raise register | 
|  | Raise an interrupt. The value will be put to the interrupt status | 
|  | register (using bitwise OR). | 
|  |  | 
|  | 0x64 (WO) : interrupt acknowledge register | 
|  | Clear an interrupt. The value will be cleared from the interrupt | 
|  | status register. This needs to be done from the ISR to stop | 
|  | generating interrupts. | 
|  |  | 
|  | 0x80 (RW) : DMA source address | 
|  | Where to perform the DMA from. | 
|  |  | 
|  | 0x88 (RW) : DMA destination address | 
|  | Where to perform the DMA to. | 
|  |  | 
|  | 0x90 (RW) : DMA transfer count | 
|  | The size of the area to perform the DMA on. | 
|  |  | 
|  | 0x98 (RW) : DMA command register, bitwise OR | 
|  | 0x01 -- start transfer | 
|  | 0x02 -- direction (0: from RAM to EDU, 1: from EDU to RAM) | 
|  | 0x04 -- raise interrupt 0x100 after finishing the DMA | 
|  |  | 
|  | IRQ controller | 
|  | -------------- | 
|  | An IRQ is generated when written to the interrupt raise register. The value | 
|  | appears in interrupt status register when the interrupt is raised and has to | 
|  | be written to the interrupt acknowledge register to lower it. | 
|  |  | 
|  | DMA controller | 
|  | -------------- | 
|  | One has to specify, source, destination, size, and start the transfer. One | 
|  | 4096 bytes long buffer at offset 0x40000 is available in the EDU device. I.e. | 
|  | one can perform DMA to/from this space when programmed properly. | 
|  |  | 
|  | Example of transferring a 100 byte block to and from the buffer using a given | 
|  | PCI address 'addr': | 
|  | addr     -> DMA source address | 
|  | 0x40000  -> DMA destination address | 
|  | 100      -> DMA transfer count | 
|  | 1        -> DMA command register | 
|  | while (DMA command register & 1) | 
|  | ; | 
|  |  | 
|  | 0x40000  -> DMA source address | 
|  | addr+100 -> DMA destination address | 
|  | 100      -> DMA transfer count | 
|  | 3        -> DMA command register | 
|  | while (DMA command register & 1) | 
|  | ; |