Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 1 | |
| 2 | EDU device |
| 3 | ========== |
| 4 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 5 | .. |
| 6 | Copyright (c) 2014-2015 Jiri Slaby |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 7 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 8 | This document is licensed under the GPLv2 (or later). |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 9 | |
| 10 | This is an educational device for writing (kernel) drivers. Its original |
| 11 | intention was to support the Linux kernel lectures taught at the Masaryk |
| 12 | University. Students are given this virtual device and are expected to write a |
| 13 | driver with I/Os, IRQs, DMAs and such. |
| 14 | |
| 15 | The devices behaves very similar to the PCI bridge present in the COMBO6 cards |
| 16 | developed under the Liberouter wings. Both PCI device ID and PCI space is |
| 17 | inherited from that device. |
| 18 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 19 | Command line switches |
| 20 | --------------------- |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 21 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 22 | ``-device edu[,dma_mask=mask]`` |
| 23 | ``dma_mask`` makes the virtual device work with DMA addresses with the given |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 24 | mask. For educational purposes, the device supports only 28 bits (256 MiB) |
| 25 | by default. Students shall set dma_mask for the device in the OS driver |
| 26 | properly. |
| 27 | |
| 28 | PCI specs |
| 29 | --------- |
| 30 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 31 | PCI ID: |
| 32 | ``1234:11e8`` |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 33 | |
| 34 | PCI Region 0: |
| 35 | I/O memory, 1 MB in size. Users are supposed to communicate with the card |
| 36 | through this memory. |
| 37 | |
| 38 | MMIO area spec |
| 39 | -------------- |
| 40 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 41 | Only ``size == 4`` accesses are allowed for addresses ``< 0x80``. |
| 42 | ``size == 4`` or ``size == 8`` for the rest. |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 43 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 44 | 0x00 (RO) : identification |
| 45 | Value is in the form ``0xRRrr00edu`` where: |
| 46 | - ``RR`` -- major version |
| 47 | - ``rr`` -- minor version |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 48 | |
| 49 | 0x04 (RW) : card liveness check |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 50 | It is a simple value inversion (``~`` C operator). |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 51 | |
| 52 | 0x08 (RW) : factorial computation |
| 53 | The stored value is taken and factorial of it is put back here. |
| 54 | This happens only after factorial bit in the status register (0x20 |
| 55 | below) is cleared. |
| 56 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 57 | 0x20 (RW) : status register |
| 58 | Bitwise OR of: |
| 59 | |
| 60 | 0x01 |
| 61 | computing factorial (RO) |
| 62 | 0x80 |
| 63 | raise interrupt after finishing factorial computation |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 64 | |
| 65 | 0x24 (RO) : interrupt status register |
| 66 | It contains values which raised the interrupt (see interrupt raise |
| 67 | register below). |
| 68 | |
| 69 | 0x60 (WO) : interrupt raise register |
| 70 | Raise an interrupt. The value will be put to the interrupt status |
| 71 | register (using bitwise OR). |
| 72 | |
| 73 | 0x64 (WO) : interrupt acknowledge register |
| 74 | Clear an interrupt. The value will be cleared from the interrupt |
| 75 | status register. This needs to be done from the ISR to stop |
| 76 | generating interrupts. |
| 77 | |
| 78 | 0x80 (RW) : DMA source address |
| 79 | Where to perform the DMA from. |
| 80 | |
| 81 | 0x88 (RW) : DMA destination address |
| 82 | Where to perform the DMA to. |
| 83 | |
| 84 | 0x90 (RW) : DMA transfer count |
| 85 | The size of the area to perform the DMA on. |
| 86 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 87 | 0x98 (RW) : DMA command register |
| 88 | Bitwise OR of: |
| 89 | |
| 90 | 0x01 |
| 91 | start transfer |
| 92 | 0x02 |
| 93 | direction (0: from RAM to EDU, 1: from EDU to RAM) |
| 94 | 0x04 |
| 95 | raise interrupt 0x100 after finishing the DMA |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 96 | |
| 97 | IRQ controller |
| 98 | -------------- |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 99 | |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 100 | An IRQ is generated when written to the interrupt raise register. The value |
| 101 | appears in interrupt status register when the interrupt is raised and has to |
| 102 | be written to the interrupt acknowledge register to lower it. |
| 103 | |
Peter Xu | eabb578 | 2016-09-28 21:03:39 +0800 | [diff] [blame] | 104 | The device supports both INTx and MSI interrupt. By default, INTx is |
| 105 | used. Even if the driver disabled INTx and only uses MSI, it still |
| 106 | needs to update the acknowledge register at the end of the IRQ handler |
| 107 | routine. |
| 108 | |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 109 | DMA controller |
| 110 | -------------- |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 111 | |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 112 | One has to specify, source, destination, size, and start the transfer. One |
| 113 | 4096 bytes long buffer at offset 0x40000 is available in the EDU device. I.e. |
| 114 | one can perform DMA to/from this space when programmed properly. |
| 115 | |
| 116 | Example of transferring a 100 byte block to and from the buffer using a given |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 117 | PCI address ``addr``: |
Jiri Slaby | b30934c | 2015-01-21 17:48:33 +0100 | [diff] [blame] | 118 | |
Peter Maydell | 4df3f19 | 2023-09-27 16:11:59 +0100 | [diff] [blame] | 119 | :: |
| 120 | |
| 121 | addr -> DMA source address |
| 122 | 0x40000 -> DMA destination address |
| 123 | 100 -> DMA transfer count |
| 124 | 1 -> DMA command register |
| 125 | while (DMA command register & 1) |
| 126 | ; |
| 127 | |
| 128 | :: |
| 129 | |
| 130 | 0x40000 -> DMA source address |
| 131 | addr+100 -> DMA destination address |
| 132 | 100 -> DMA transfer count |
| 133 | 3 -> DMA command register |
| 134 | while (DMA command register & 1) |
| 135 | ; |