1 2 * Constants can't be bigger than 32 bits. For example: 3 constants mcg_ctl_val "Global MC control values" { 4 mc_enable = 0xffffffffffffffff; 5 mc_disable = 0x0; 6 }; 7 - again. 8 9 * Required additional checks are now: 10 - Constant values all fit into the bit width specified 11 12 * How will we do device inheritance? Clearly the new device is a 13 new type, but it also needs a new operation for every register, 14 even those inherited from the base device type. This suggests that 15 register definitions should always be copied from the base type, 16 but register type definitions (and constant declarations) should 17 simply be referenced. 18 19 New syntax for inheritance: 20 1) extends(xapic) as an extra device attribute. 21 2) override register foo ... to override a register definition. 22 3) elide register bar; removes defn of bar from the new device. 23 24 * Generalize register field attributes. Specify fixed values 25 properly, as either a literal, or a constant value name, or 26 (possibly) a compile-time expression. Split up whether the driver 27 can read or write the field, and in what way, from what 28 consequences there are of reading or writing the field. 29 30 What is the difference between the read cycles permissible by the 31 hardware, and the read operations that the user might want to be able 32 to initiate? 33 34 Well, whether the hardware allows reads or not is simply a bit. 35 Hardware-readable: boolean. False => never generate a read 36 cycle. This is a property of a register, not a field! 37 38 What reads the user is allowed to perform is always one of: 39 R : 'read_value' : Return any value to user (expose a read operation) 40 RF: 'read_as' Always same constant value (expose sanity check to drivers) 41 RC: 'read_clears' Reads as some value, and also clears. 42 RN: 'no_read' Can't be read. 43 These are properties of fields; register properties are templates 44 for these. 45 46 Can you allow a hardware write or not? 47 If you can, what are the constraints on this? These are field 48 properties, but might apply to the register as a whole. 49 50 Options for writing: 51 W : 'write_value' Set to any value of a type (expose a write operation) 52 WN: 'no_write' Cannot be written/writes ignored (not exposed to user) 53 WF: 'write_as' Must write a specific value (not exposed to user) 54 WP: 'preserve' Must preserve previous value (not exposed to user) 55 WC: 'write_to_clear(v)' Must write a specific value to clear register 56 WS: 'write_to_set(v)' Must write a specific value to set register 57 58 Options for other actions: 59 sticky: once written, value will never change. 60 61 Shorthand: 62 rw => read_value write_value 63 ro => readable no_write 64 wo => no_read writeable 65 always(v) => read_as(v) write_as(v) 66 mbz => no_read write_as(0) 67 mb1 => no_read write_as(1s) 68 rsvd => no_read preserve 69 ros => readable no_write sticky 70 rwc => readable writeable write_to_clear(1s) 71 rwzc => readable writeable write_to_clear(0) 72 rws => readable writeable sticky 73 74 Functions to generate for a field: 75 readable, read_as => read_field 76 read_as => check_field 77 read_clears, write_to_clear(v) => clear_field 78 writeable => write_field 79 80 * Register fields that can be given an initial value: initial(val) 81 82 * Variant format types. A format can have several different 83 variants. Some fields are common to all variants, others only 84 appear in some variants. There must be a way of determining which 85 variant a format is 86 87 * Back-end to print out memory map of device, or even pictures. 88 * Selectively enable/disable specific checks 89 * Collect all parse errors before exiting. 90 * Generate device models. 91 92 * Devil's notion of 'values', derived from registers (e.g. by 93 concatenating two fields from different registers together). This 94 should allow constant parts of values: for example, in PTEs, one 95 needs to concat a bit field with a bunch of zeros to get an 96 address. 97 98 * Preconditions and postconditions, e.g. for handling register select 99 registers. These also tend to imply software state variables used 100 to track the state of the hardware for the driver. 101 102 * Higher-level state machine constraints on how to program the 103 hardware. For example, to read the ESR below you must first 104 write once to it. To clear it you need to perform two 105 back-to-back writes. Don't ask.... 106 107 * Messages, as opposed to addresses. Composing access to devices 108 that can only be accessed by sending messages using writes to 109 110 * Register overlap checks should allow non-'also' registers to 111 overlap if one is non-writeable and the other is non-readable. 112 113 * Compile time checks: 114 - Duplicate register names 115 - Duplicate register type names 116 - Overlapping address spaces 117 - Type mismatch between device arg and register base 118 - Undefined register types 119 120 * What are the name spaces? 121 - Register and constant types 122 - Register names 123 - Constant value names 124 - Fields within a particular format 125 - Device parameters 126 127 * Good (bad) test cases for Mackerel: 128 - PageTableEntries for x86, with alternative values 129 (e.g. superpages) 130 - ARM coprocessor registers 131 - x86 CPUID instructions, including clockout of cache params 132 - Access modes for LPC PIC, DMAC, and Clock hardware 133 134 135------------------------- 136Experiences: 137 138 - In contrast to Devil, accessing device registers is easier these 139 days since there is lots of address space. Consequently, 140 pre-conditions on registers and indexes are much less of an issue, 141 and Mackerel doesn't support them 142 143 - Mackerel specs are intended to be as close as possible to the data 144 sheets. While Devil wanted manufacturers to publish Devil specs 145 along with data sheets, we are less idealistic. We want to make it 146 as easy as possible for a programmer to type in a spec from teh 147 data sheet. 148 149 - What is hard these days is that registers have lots of fields, and 150 reserved fields which must be read before being written. 151 152 - HyperV MSR problem: RSVD registers. 153 154 - It was invaluable having working driver for APIC while debugging 155 the Mackerel version. Hopefully this is not the case once Mackerel 156 is debugging and reliable. 157 158 - It has got to be reliable: you need to feel comfortable Mackeral 159 isn't crashing your code. 160 161 - Mackerel code is transparent: it's readable, and intuitive. 162 163 - Most existing code uses (a) mapped structs, (b) bitfields, (c) 164 Macros giving masks and shifts 165 166 - We can do full device dumps 167 168 - Source code inline is shorter and more intuitive. 169 170 - Specs are easier to write than structs or macros. 171 172 - Mackerel errors do get caught (esp. register widths catch incorrect 173 field sizes). 174 175 - We build all our drivers using Mackerel now, plus MSRs. 176 177 - Haskell was good. Parsing, etc. Formatting. 178 179 - Generated code is remarkably efficient. Assembly looks almost the 180 same. 181 182 - Same file used for user and kernel space. 183 184 - Lots of volatile errors. Fix once in Mackerel.h, and then done. 185 Programmer is saved from having to deal with them further. 186 187 - Still dependent on GCC features, but fewer of them appear in inline 188 code and those that do (e.g. inline struct literals) are more 189 syntactic sugar than code directives like volatile. This makes us 190 more compiler independent. 191 192 - Descriptions are really nice. Lots of ad-hoc code got written to 193 do this. snprintf is the right way. 194 195 - Mackerel-generated files are large, with many types, and many 196 inlined functions. Generated code, however, is very compact. 197 198 - List devices so far. 199 200 - RWCS, RWS, etc. can be supported (e.g. device models). 201 202 - Code inflates by approx. 10x (.dev -> .h) 203 204 - Takes a while to type in all the registers, but (1) it's easier 205 than working out struct formats, (2) it's basically transcribing 206 the data sheet, so a good way of getting acquainted with the 207 device. 208 209----------------------- 210 211acpi_ec.dev:1:1: File acpi_ec.dev describes dev EC not acpi_ec 212arm_icp_pic.dev:1:1: File arm_icp_pic.dev describes dev arm_icp_pic0 not arm_icp_pic 213hpet.dev:1:1: File hpet.dev describes dev HPET not hpet 214ixp2800_icp_pic.dev:1:1: File ixp2800_icp_pic.dev describes dev ixp2800_icp_pic0 not ixp2800_icp_pic 215ixp2800_uart.dev:1:1: File ixp2800_uart.dev describes dev IXP2800_UART not ixp2800_uart 216lpc_dma.dev:1:1: File lpc_dma.dev describes dev LPC_dma not lpc_dma 217lpc_ioapic.dev:1:1: File lpc_ioapic.dev describes dev LPC_IOAPIC not lpc_ioapic 218lpc_pic.dev:1:1: File lpc_pic.dev describes dev LPC_PIC not lpc_pic 219lpc_rtc.dev:1:1: File lpc_rtc.dev describes dev LPC_rtc not lpc_rtc 220lpc_rtc_spaces.dev:1:1: File lpc_rtc_spaces.dev describes dev LPC_rtc not lpc_rtc_spaces 221lpc_timer.dev:1:1: File lpc_timer.dev describes dev LPC_timer not lpc_timer 222pc16550d_uart.dev:1:1: File pc16550d_uart.dev describes dev PC16550D_UART not pc16550d_uart 223pl011_uart.dev:1:1: File pl011_uart.dev describes dev PL011_UART not pl011_uart 224