Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/hpcsh/dev/hd64461 Fix workaround for SH-3 PCMCIA bu...
details: https://anonhg.NetBSD.org/src/rev/215fa15bd47b
branches: trunk
changeset: 989061:215fa15bd47b
user: rin <rin%NetBSD.org@localhost>
date: Mon Oct 11 02:30:00 2021 +0000
description:
Fix workaround for SH-3 PCMCIA bug in accordance with description
found in TECH I vol. 14 (CQ Publishing, Tokyo, 2002, in Japanese),
as well as experiment on real hardware:
Byte-access to area 6 becomes word-access (both CE1# and CE2# are
wrongly asserted), if preceding access is word-wise. Inserting a
dummy byte-access works around the problem. Area 5 is not affected.
Therefore,
(1) Insert a dummy byte-read before all byte-wise operations.
(2) Restrict the workaround to area 6 (channel 0), and rename
fixup_sh3_pcmcia_area() to fixup_sh3_pcmcia_area6() for clarity.
Also, we used to use 0xba000000 (== HD64461_PCC0_IOBASE) as target
for the dummy read. However, this can modify device states, which
breaks ep(4) at least. Thus,
(3) Use HD64461_PCC0_MEMBASE as target for the dummy read. This is
assigned to attribute memory space, and byte-read should be
harmless.
diffstat:
sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c | 50 ++++++++++++++++++++++-------
1 files changed, 38 insertions(+), 12 deletions(-)
diffs (111 lines):
diff -r 6d7bc0835dd7 -r 215fa15bd47b sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c
--- a/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c Mon Oct 11 01:49:08 2021 +0000
+++ b/sys/arch/hpcsh/dev/hd64461/hd64461pcmcia.c Mon Oct 11 02:30:00 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hd64461pcmcia.c,v 1.54 2021/08/07 16:18:54 thorpej Exp $ */
+/* $NetBSD: hd64461pcmcia.c,v 1.55 2021/10/11 02:30:00 rin Exp $ */
/*-
* Copyright (c) 2001, 2002, 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hd64461pcmcia.c,v 1.54 2021/08/07 16:18:54 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hd64461pcmcia.c,v 1.55 2021/10/11 02:30:00 rin Exp $");
#include "opt_hd64461pcmcia.h"
@@ -223,17 +223,37 @@
#ifdef HD64461PCMCIA_DEBUG
STATIC void hd64461pcmcia_info(struct hd64461pcmcia_softc *);
#endif
-/* fix SH3 Area[56] bug */
-STATIC void fixup_sh3_pcmcia_area(bus_space_tag_t);
+
+/*
+ * Workaround for SH-3 PCMCIA bug on area 6:
+ *
+ * According to TECH I vol. 14 (CQ Publishing, Tokyo, 2002) p. 184,
+ * byte-access to area 6 becomes word-access if preceding access is
+ * word-wise. Inserting a dummy byte-access works around the problem.
+ * Area 5 is not affected by this bug.
+ *
+ * Therefore, we insert a dummy byte-wise read to HD64461_PCC0_MEMBASE
+ * before any byte-access to area 6 (channel 0).
+ *
+ * Note that we used to use HD64461_PCC0_IOBASE for this purpose. But,
+ * read access to that register can modify device states, which breaks
+ * ep(4) at least. On the other hand, since HD64461_PCC0_MEMBASE is
+ * assigned to attribute memory, read access should be harmless.
+ */
+STATIC void fixup_sh3_pcmcia_area6(bus_space_tag_t);
#define _BUS_SPACE_ACCESS_HOOK() \
-do { \
- uint8_t dummy __attribute__((__unused__)) = \
- *(volatile uint8_t *)0xba000000; \
-} while (/*CONSTCOND*/0)
+ do { \
+ uint8_t dummy __unused = \
+ *(volatile uint8_t *)HD64461_PCC0_MEMBASE; \
+ } while (0)
+_BUS_SPACE_READ(_sh3_pcmcia_bug, 1, 8)
+_BUS_SPACE_READ_MULTI(_sh3_pcmcia_bug, 1, 8)
+_BUS_SPACE_READ_REGION(_sh3_pcmcia_bug, 1, 8)
_BUS_SPACE_WRITE(_sh3_pcmcia_bug, 1, 8)
_BUS_SPACE_WRITE_MULTI(_sh3_pcmcia_bug, 1, 8)
_BUS_SPACE_WRITE_REGION(_sh3_pcmcia_bug, 1, 8)
_BUS_SPACE_SET_MULTI(_sh3_pcmcia_bug, 1, 8)
+_BUS_SPACE_COPY_REGION(_sh3_pcmcia_bug, 1, 8)
#undef _BUS_SPACE_ACCESS_HOOK
#define DELAY_MS(x) delay((x) * 1000)
@@ -386,7 +406,8 @@
bus_space_alloc(ch->ch_memt, 0, 0x00ffffff, 0x01000000,
0x01000000, 0x01000000, 0, &ch->ch_membase_addr,
&ch->ch_memh);
- fixup_sh3_pcmcia_area(ch->ch_memt);
+ if (channel == CHANNEL_0)
+ fixup_sh3_pcmcia_area6(ch->ch_memt);
/* Common memory space extent */
ch->ch_memsize = 0x01000000;
@@ -394,7 +415,8 @@
ch->ch_cmemt[i] = bus_space_create(0, "PCMCIA common memory",
membase + 0x01000000,
ch->ch_memsize);
- fixup_sh3_pcmcia_area(ch->ch_cmemt[i]);
+ if (channel == CHANNEL_0)
+ fixup_sh3_pcmcia_area6(ch->ch_cmemt[i]);
}
/* I/O port extent and interrupt staff */
@@ -406,7 +428,7 @@
ch->ch_iot = bus_space_create(0, "PCMCIA I/O port",
HD64461_PCC0_IOBASE,
ch->ch_iosize);
- fixup_sh3_pcmcia_area(ch->ch_iot);
+ fixup_sh3_pcmcia_area6(ch->ch_iot);
hd6446x_intr_establish(HD64461_INTC_PCC0, IST_LEVEL, IPL_TTY,
hd64461pcmcia_channel0_intr, ch);
@@ -1081,14 +1103,18 @@
}
STATIC void
-fixup_sh3_pcmcia_area(bus_space_tag_t t)
+fixup_sh3_pcmcia_area6(bus_space_tag_t t)
{
struct hpcsh_bus_space *hbs = (void *)t;
+ hbs->hbs_r_1 = _sh3_pcmcia_bug_read_1;
+ hbs->hbs_rm_1 = _sh3_pcmcia_bug_read_multi_1;
+ hbs->hbs_rr_1 = _sh3_pcmcia_bug_read_region_1;
hbs->hbs_w_1 = _sh3_pcmcia_bug_write_1;
hbs->hbs_wm_1 = _sh3_pcmcia_bug_write_multi_1;
hbs->hbs_wr_1 = _sh3_pcmcia_bug_write_region_1;
hbs->hbs_sm_1 = _sh3_pcmcia_bug_set_multi_1;
+ hbs->hbs_c_1 = _sh3_pcmcia_bug_copy_region_1;
}
#ifdef HD64461PCMCIA_DEBUG
Home |
Main Index |
Thread Index |
Old Index