Hi Geert,
Note that both 16 and 32 bit accesses will return 8 bit results only, due
to the way the address and data bus are wired on the ROM ISA adapter. I
hope this is the correct behavior.
I don't think that's correct. Shouldn't 16-bit resp. 32-bit accesses be
emulated using 2 resp. 4 8-bit accesses instead?
OK, this emulates word and longword access by multiple byte accesses.
Goes on top of my previous patch (and should be included in the Debian
package).
Michael
--- include/asm-m68k/raw_io.h.ms-submitted 2006-11-07 13:07:43.000000000 +0100
+++ include/asm-m68k/raw_io.h 2007-05-31 15:31:25.000000000 +0200
@@ -62,28 +62,74 @@
*
* Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
* For writes, address lines A1-A8 are latched to ISA data lines D0-D7
- * (meaning the bit pattern on A1-A8 can be read back as byte).
+ * (meaning the bit pattern on A1-A8 can be read back as byte on D8-D15).
+ *
+ * Proper conversion of addr (i.e., shifting address bits 0-4 up by 9 bits)
+ * has to be taken care of by ISA address translation code in caller. The
+ * offset of 0x10000 in the write functions is the offset between read and
+ * write ROM base address (/ROM3 vs /ROM4)
+ *
+ * Reads and writes are byte only. Data arrive in the high byte of a word,
+ * hence the shifts.
*
- * Reads and writes are byte only.
+ * For word and longword accesses, emulate by byte-wise reads and shifts.
*/
#if defined(CONFIG_ATARI_ROM_ISA)
#define rom_in_8(addr) \
({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
#define rom_in_be16(addr) \
- ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
+ ({ u16 __w = (*(__force volatile u16 *) (addr)); \
+ u16 __v = (*(__force volatile u16 *) (addr)); __w &= __v >> 8; __w; })
#define rom_in_be32(addr) \
- ({ u32 __v = (*(__force volatile u32 *) (addr)); __v >>= 8; __v; })
+ ({ u32 __y = (*(__force volatile u32 *) (addr)); \
+ u32 __x = (*(__force volatile u32 *) (addr)); \
+ u32 __w = (*(__force volatile u32 *) (addr)); \
+ u32 __v = (*(__force volatile u32 *) (addr)); __y &= __x >> 8; __w &= __v >> 8; __w &= __y << 16; __w; })
#define rom_in_le16(addr) \
- ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
+ ({ u16 __v = (*(__force volatile u16 *) (addr)); \
+ u16 __w = (*(__force volatile u16 *) (addr)); __w &= __v >> 8; __w; })
#define rom_in_le32(addr) \
- ({ u32 __v = le32_to_cpu(*(__force volatile u32 *) (addr)); __v >>= 8; __v; })
-
-#define rom_out_8(addr,b) ({u8 __w, __v = (b); __w = ((*(__force volatile u8 *) ((addr) + 0x10000 + (__v<<1)))); })
-#define rom_out_be16(addr,w) ({u16 __w, __v = (w); __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
-#define rom_out_be32(addr,l) ({u32 __w, __v = (l); __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
-#define rom_out_le16(addr,w) ({u16 __w, __v = cpu_to_le16(w); __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
-#define rom_out_le32(addr,l) ({u32 __w, __v = cpu_to_le32(l); __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
+ ({ u32 __v = (*(__force volatile u32 *) (addr)); \
+ u32 __w = (*(__force volatile u32 *) (addr)); \
+ u32 __x = (*(__force volatile u32 *) (addr)); \
+ u32 __y = (*(__force volatile u32 *) (addr)); __y &= __x >> 8; __w &= __v >> 8; __w &= __y << 16; __w; })
+
+#define rom_out_8(addr,b) \
+ ({u8 __w, __v = (b); \
+ __w = ((*(__force volatile u8 *) ((addr) + 0x10000 + (__v<<1)))); })
+#define rom_out_be16(addr,w) \
+ ({u16 __w, __v; \
+ __v = (w) >> 8; \
+ __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = (w) & 0x0f; \
+ __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
+#define rom_out_be32(addr,l) \
+ ({u32 __w, __v; \
+ __v = (l) >> 24; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = ((l) >> 16) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = ((l) >> 8) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = (l) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
+#define rom_out_le16(addr,w) \
+ ({u16 __w, __v; \
+ __v = (w) & 0x0f; \
+ __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = (w) >> 8; \
+ __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
+#define rom_out_le32(addr,l) \
+ ({u32 __w, __v; \
+ __v = (l) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = ((l) >> 8) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = ((l) >> 16) & 0x0f; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); \
+ __v = (l) >> 24; \
+ __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
#define raw_rom_inb rom_in_8
#define raw_rom_inw rom_in_be16
-
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html