diff --git a/Makefile b/Makefile
index 7350b89..631e16f 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,8 @@ info:
clean:
@echo -n "Cleaning up..."
- @rm -rf $(ODIR) forth.dict.core
+ @rm -rf $(ODIR) forth.dict.core
+ @find . -type f -name "*~" -exec rm \{\} \;
@echo " ok"
directories: clean
@@ -22,6 +23,7 @@ directories: clean
@mkdir -p $(ODIR)/target/arch/ppc/pearpc
@mkdir -p $(ODIR)/target/arch/ppc/mol
@mkdir -p $(ODIR)/target/arch/x86/xbox
+ @mkdir -p $(ODIR)/target/sparc32/libgcc
@mkdir -p $(ODIR)/target/kernel
@mkdir -p $(ODIR)/target/modules
@mkdir -p $(ODIR)/target/fs/grubfs
diff --git a/arch/sparc32/build.xml b/arch/sparc32/build.xml
index 1fec32e..1107db3 100644
--- a/arch/sparc32/build.xml
+++ b/arch/sparc32/build.xml
@@ -1,6 +1,9 @@
+
+
+
@@ -11,6 +14,7 @@
+
@@ -18,40 +22,53 @@
+
+
+
+
+
+
+
- $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^ `$(CC) --print-libgcc`
+ $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^
$(NM) $@.nostrip | sort > $(ODIR)/openbios-multiboot.syms
cp $@.nostrip $@
$(STRIP) $@
-
-
+
+
+
- $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^ `$(CC) --print-libgcc`
+ $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^
$(NM) $@.nostrip | sort > $(ODIR)/openbios-plain.syms
cp $@.nostrip $@
$(STRIP) $@
-
-
+
+
+
@@ -77,13 +94,13 @@
- $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^ `$(CC) --print-libgcc`
+ $(LD) -N -T arch/sparc32/ldscript -o $@.nostrip $^
$(NM) $@.nostrip | sort > $(ODIR)/openbios-builtin.syms
cp $@.nostrip $@
$(STRIP) $@
-
-
+
+
@@ -91,6 +108,7 @@
+
diff --git a/arch/sparc32/builtin.c b/arch/sparc32/builtin.c
index b351c70..46309b8 100644
--- a/arch/sparc32/builtin.c
+++ b/arch/sparc32/builtin.c
@@ -1,4 +1,4 @@
-/* tag: openbios forth starter for builtin dictionary for amd64
+/* tag: openbios forth starter for builtin dictionary for sparc32
*
* Copyright (C) 2003 Stefan Reinauer
*
diff --git a/arch/sparc32/entry.S b/arch/sparc32/entry.S
index 3d30545..0ea3381 100644
--- a/arch/sparc32/entry.S
+++ b/arch/sparc32/entry.S
@@ -181,7 +181,7 @@ entry:
bl 1b
add %o0, 0x4, %o0
- set 0x10000, %sp ! XXX
+ set _estack, %sp
mov 0, %fp
mov 2, %g1
wr %g1, 0x0, %wim ! make window 1 invalid
diff --git a/arch/sparc32/init.fs b/arch/sparc32/init.fs
index 3a2eb9e..75c14e2 100644
--- a/arch/sparc32/init.fs
+++ b/arch/sparc32/init.fs
@@ -4,43 +4,6 @@
\ ." 0 > boot hd:2,\boot\vmlinuz root=/dev/hda2" cr
; DIAG-initializer
-" /" find-device
- " SUNW,SparcStation-5" encode-string " name" property
- " " encode-string " idprom" property
- " SparcStation" encode-string " banner-name" property
- " sun4m" encode-string " compatible" property
-
-new-device
- " memory" device-name
- \ 12230 encode-int " reg" property
- external
- : open true ;
- : close ;
- \ claim ( phys size align -- base )
- \ release ( phys size -- )
-finish-device
-
-new-device
- " STP1012PGA" device-name
- " cpu" device-type
- " " encode-string " performance-monitor" property
- d# 256 encode-int " mmu-nctx" int-property
- d# 32 encode-int " cache-line-size" int-property
- d# 512 encode-int " cache-nlines" int-property
- 1 encode-int " mid" int-property
-finish-device
-
-new-device
- " iommu" device-name
-finish-device
-
-" /iommu" find-device
-new-device
- " sbus" device-name
- " hierarchical" device-type
-finish-device
-
-
: make-openable ( path )
find-dev if
begin ?dup while
diff --git a/arch/sparc32/libgcc/__divdi3.c b/arch/sparc32/libgcc/__divdi3.c
new file mode 100644
index 0000000..3641396
--- /dev/null
+++ b/arch/sparc32/libgcc/__divdi3.c
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include
+#include
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+int64_t __divdi3(int64_t num, int64_t den)
+{
+ int minus = 0;
+ int64_t v;
+
+ if ( num < 0 ) {
+ num = -num;
+ minus = 1;
+ }
+ if ( den < 0 ) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ v = __udivmoddi4(num, den, NULL);
+ if ( minus )
+ v = -v;
+
+ return v;
+}
diff --git a/arch/sparc32/libgcc/__udivdi3.c b/arch/sparc32/libgcc/__udivdi3.c
new file mode 100644
index 0000000..901ce2a
--- /dev/null
+++ b/arch/sparc32/libgcc/__udivdi3.c
@@ -0,0 +1,13 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include
+#include
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+uint64_t __udivdi3(uint64_t num, uint64_t den)
+{
+ return __udivmoddi4(num, den, NULL);
+}
diff --git a/arch/sparc32/libgcc/__udivmoddi4.c b/arch/sparc32/libgcc/__udivmoddi4.c
new file mode 100644
index 0000000..e77be3a
--- /dev/null
+++ b/arch/sparc32/libgcc/__udivmoddi4.c
@@ -0,0 +1,33 @@
+#include
+
+extern void __divide_error();
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p)
+{
+ uint64_t quot = 0, qbit = 1;
+
+ if ( den == 0 ) {
+ __divide_error();
+ return 0; /* If trap returns... */
+ }
+
+ /* Left-justify denominator and count shift */
+ while ( (int64_t)den >= 0 ) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while ( qbit ) {
+ if ( den <= num ) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if ( rem_p )
+ *rem_p = num;
+
+ return quot;
+}
diff --git a/arch/sparc32/libgcc/__umoddi3.c b/arch/sparc32/libgcc/__umoddi3.c
new file mode 100644
index 0000000..c007d48
--- /dev/null
+++ b/arch/sparc32/libgcc/__umoddi3.c
@@ -0,0 +1,16 @@
+/*
+ * arch/i386/libgcc/__umoddi3.c
+ */
+
+#include
+#include
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
+
+uint64_t __umoddi3(uint64_t num, uint64_t den)
+{
+ uint64_t v;
+
+ (void) __udivmoddi4(num, den, &v);
+ return v;
+}
diff --git a/arch/sparc32/libgcc/ashldi3.c b/arch/sparc32/libgcc/ashldi3.c
new file mode 100644
index 0000000..008403e
--- /dev/null
+++ b/arch/sparc32/libgcc/ashldi3.c
@@ -0,0 +1,62 @@
+/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define BITS_PER_UNIT 8
+
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (USItype)uu.s.low << -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.low >> bm;
+ w.s.low = (USItype)uu.s.low << b;
+ w.s.high = ((USItype)uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/sparc32/libgcc/ashrdi3.c b/arch/sparc32/libgcc/ashrdi3.c
new file mode 100644
index 0000000..78efb65
--- /dev/null
+++ b/arch/sparc32/libgcc/ashrdi3.c
@@ -0,0 +1,63 @@
+/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define BITS_PER_UNIT 8
+
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/sparc32/libgcc/build.xml b/arch/sparc32/libgcc/build.xml
new file mode 100644
index 0000000..a746350
--- /dev/null
+++ b/arch/sparc32/libgcc/build.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/arch/sparc32/multiboot.c b/arch/sparc32/multiboot.c
index c35ab0f..d5877d4 100644
--- a/arch/sparc32/multiboot.c
+++ b/arch/sparc32/multiboot.c
@@ -46,7 +46,7 @@ void collect_multiboot_info(struct sys_info *info)
struct multiboot_info *mbinfo;
struct multiboot_mmap *mbmem;
unsigned mbcount, mbaddr;
- int i;
+ unsigned int i;
struct memrange *mmap;
int mmap_count;
module_t *mod;
diff --git a/arch/sparc32/openbios.c b/arch/sparc32/openbios.c
index 8d7c0b1..7f09b73 100644
--- a/arch/sparc32/openbios.c
+++ b/arch/sparc32/openbios.c
@@ -8,6 +8,7 @@
#include "openbios/config.h"
#include "openbios/bindings.h"
+#include "openbios/drivers.h"
#include "asm/types.h"
#include "dict.h"
#include "openbios/kernel.h"
@@ -47,9 +48,11 @@ arch_init( void )
void setup_timers(void);
modules_init();
-#ifdef CONFIG_DRIVER_IDE
- setup_timers();
- ob_ide_init();
+#ifdef CONFIG_DRIVER_SBUS
+ ob_sbus_init();
+#endif
+#ifdef CONFIG_DRIVER_ESP
+ ob_esp_init();
#endif
device_end();
bind_func("platform-boot", boot );
diff --git a/arch/sparc32/tree.fs b/arch/sparc32/tree.fs
new file mode 100644
index 0000000..3b9f3e2
--- /dev/null
+++ b/arch/sparc32/tree.fs
@@ -0,0 +1,234 @@
+
+" /" find-device
+ 2 encode-int " #address-cells" property
+ 1 encode-int " #size-cells" property
+ " SUNW,SparcStation-5" encode-string " name" property
+ " " encode-string " idprom" property
+ " SparcStation" encode-string " banner-name" property
+ " sun4m" encode-string " compatible" property
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+
+new-device
+ " memory" device-name
+ external
+ : open true ;
+ : close ;
+ \ claim ( phys size align -- base )
+ \ release ( phys size -- )
+finish-device
+
+new-device
+ " STP1012PGA" device-name
+ " cpu" device-type
+ d# 256 encode-int " mmu-nctx" property
+ d# 32 encode-int " cache-line-size" property
+ d# 512 encode-int " cache-nlines" property
+ 1 encode-int " mid" property
+finish-device
+
+new-device
+ " iommu" device-name
+ 2 encode-int " #address-cells" property
+ 1 encode-int " #size-cells" property
+ h# 0 encode-int h# 10000000 encode-int encode+ h# 00000300 encode-int encode+ " reg" property
+ external
+ : open cr ." opening iommu" cr true ;
+ : close ;
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+finish-device
+
+" /iommu" find-device
+new-device
+ " sbus" device-name
+ " hierarchical" device-type
+ 2 encode-int " #address-cells" property
+ 1 encode-int " #size-cells" property
+ h# 0 encode-int h# 0 encode-int encode+ h# 0 encode-int encode+ h# 30000000 encode-int encode+ h# 10000000 encode-int encode+
+ h# 1 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 40000000 encode-int encode+ h# 10000000 encode-int encode+
+ h# 2 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 50000000 encode-int encode+ h# 10000000 encode-int encode+
+ h# 3 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 60000000 encode-int encode+ h# 10000000 encode-int encode+
+ h# 4 encode-int encode+ h# 0 encode-int encode+ h# 0 encode-int encode+ h# 70000000 encode-int encode+ h# 10000000 encode-int encode+
+ " ranges" property
+ h# 0 encode-int h# 10001000 encode-int encode+ h# 00000028 encode-int encode+ " reg" property
+ external
+ : open cr ." opening SBus" cr true ;
+ : close ;
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ " SUNW,CS4231" device-name
+ " serial" device-type
+ 5 encode-int 0 encode-int encode+ " intr" property
+ 5 encode-int " interrupts" property
+ h# 3 encode-int h# 0c000000 encode-int encode+ h# 00000040 encode-int encode+ " reg" property
+ " audio" encode-string " alias" property
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ " SUNW,bpp" device-name
+ h# 4 encode-int h# 0c800000 encode-int encode+ h# 0000001c encode-int encode+ " reg" property
+ h# 33 encode-int 0 encode-int encode+ " intr" property
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ " SUNW,tcx" device-name
+ " display" device-type
+ h# 1d encode-int " vbporch" property
+ h# 90 encode-int " hbporch" property
+ h# 06 encode-int " vsync" property
+ h# 88 encode-int " hsync" property
+ h# 03 encode-int " vfporch" property
+ h# 18 encode-int " hfporch" property
+ h# 03dfd240 encode-int " pixfreq" property
+ h# 3c encode-int " vfreq" property
+ h# 300 encode-int " height" property
+ h# 400 encode-int " width" property
+ h# 400 encode-int " linebytes" property
+ d# 24 encode-int " depth" property
+ " no" encode-string " tcx-8-bit" property
+ 5 encode-int 0 encode-int encode+ " intr" property
+ 5 encode-int " interrupts" property
+ 2 encode-int h# 00800000 encode-int encode+ h# 00100000 encode-int encode+
+ 2 encode-int encode+ h# 02000000 encode-int encode+ h# 00000001 encode-int encode+
+ 2 encode-int encode+ h# 04000000 encode-int encode+ h# 00800000 encode-int encode+
+ 2 encode-int encode+ h# 06000000 encode-int encode+ h# 00800000 encode-int encode+
+ 2 encode-int encode+ h# 0a000000 encode-int encode+ h# 00000001 encode-int encode+
+ 2 encode-int encode+ h# 0c000000 encode-int encode+ h# 00000001 encode-int encode+
+ 2 encode-int encode+ h# 0e000000 encode-int encode+ h# 00000001 encode-int encode+
+ 2 encode-int encode+ h# 00700000 encode-int encode+ h# 00001000 encode-int encode+
+ 2 encode-int encode+ h# 00200000 encode-int encode+ h# 00000004 encode-int encode+
+ 2 encode-int encode+ h# 00300000 encode-int encode+ h# 0000081c encode-int encode+
+ 2 encode-int encode+ h# 00000000 encode-int encode+ h# 00010000 encode-int encode+
+ 2 encode-int encode+ h# 00240000 encode-int encode+ h# 00000004 encode-int encode+
+ 2 encode-int encode+ h# 00280000 encode-int encode+ h# 00000001 encode-int encode+
+ " reg" property
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ " espdma" device-name
+ h# 4 encode-int h# 08400000 encode-int encode+ h# 00000010 encode-int encode+ " reg" property
+ external
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ " ledma" device-name
+ h# 4 encode-int h# 08400010 encode-int encode+ h# 00000020 encode-int encode+ " reg" property
+ h# 3f encode-int " burst-sizes" property
+ external
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+finish-device
+
+" /iommu/sbus/ledma" find-device
+new-device
+ " le" device-name
+ " network" device-type
+ h# 4 encode-int h# 08c00000 encode-int encode+ h# 00000004 encode-int encode+ " reg" property
+ h# 7 encode-int " busmaster-regval" property
+ h# 26 encode-int 0 encode-int encode+ " intr" property
+finish-device
+
+" /iommu/sbus" find-device
+new-device
+ \ disabled with xxx, bad interactions with Linux
+ " xxxpower-management" device-name
+ h# 4 encode-int h# 0a000000 encode-int encode+ h# 00000010 encode-int encode+ " reg" property
+finish-device
+
+
+\ obio (on-board IO)
+" /" find-device
+new-device
+ " obio" device-name
+ " hierarchical" device-type
+ 2 encode-int " #address-cells" property
+ 1 encode-int " #size-cells" property
+ h# 0 encode-int h# 0 encode-int encode+ h# 0 encode-int encode+ h# 71000000 encode-int encode+ h# 01000000 encode-int encode+
+ " ranges" property
+ external
+ : open cr ." opening obio" cr true ;
+ : close ;
+ : encode-unit encode-unit-sbus ;
+ : decode-unit decode-unit-sbus ;
+finish-device
+
+" /obio" find-device
+new-device
+ " SUNW,fdtwo" device-name
+ " block" device-type
+ h# 0 encode-int h# 00400000 encode-int encode+ h# 0000000f encode-int encode+ " reg" property
+ h# 2b encode-int 0 encode-int encode+ " intr" property
+finish-device
+
+" /obio" find-device
+new-device
+ " auxio" device-name
+ h# 0 encode-int h# 00900000 encode-int encode+ h# 00000001 encode-int encode+ " reg" property
+finish-device
+
+" /obio" find-device
+new-device
+ " counter" device-name
+ h# 0 encode-int h# 00d00000 encode-int encode+ h# 00000010 encode-int encode+
+ h# 0 encode-int encode+ h# 00d10000 encode-int encode+ h# 00000010 encode-int encode+
+ " reg" property
+finish-device
+
+" /obio" find-device
+new-device
+ " eeprom" device-name
+ h# 0 encode-int h# 00200000 encode-int encode+ h# 00002000 encode-int encode+ " reg" property
+ " mk48t08" model
+finish-device
+
+" /obio" find-device
+new-device
+ " interrupt" device-name
+ h# 0 encode-int h# 00e00000 encode-int encode+ h# 00000010 encode-int encode+
+ h# 0 encode-int encode+ h# 00e10000 encode-int encode+ h# 00000010 encode-int encode+
+ " reg" property
+finish-device
+
+" /obio" find-device
+new-device
+ " power" device-name
+ h# 0 encode-int h# 00910000 encode-int encode+ h# 00000001 encode-int encode+ " reg" property
+ h# 22 encode-int 0 encode-int encode+ " intr" property
+finish-device
+
+" /obio" find-device
+new-device
+ " slavioconfig" device-name
+ h# 0 encode-int h# 00800000 encode-int encode+ h# 00000001 encode-int encode+ " reg" property
+finish-device
+
+" /obio" find-device
+new-device
+ " zs" device-name
+ " serial" device-type
+ h# 0 encode-int h# 00000000 encode-int encode+ h# 00000008 encode-int encode+ " reg" property
+ 1 encode-int " slave" property
+ h# 2c encode-int 0 encode-int encode+ " intr" property
+ 1 encode-int " keyboard" property
+ 1 encode-int " mouse" property
+finish-device
+
+" /obio" find-device
+new-device
+ " zs" device-name
+ " serial" device-type
+ h# 0 encode-int h# 00100000 encode-int encode+ h# 00000008 encode-int encode+ " reg" property
+ 0 encode-int " slave" property
+ h# 2c encode-int 0 encode-int encode+ " intr" property
+finish-device
diff --git a/config/examples/cross-sparc32_config.xml b/config/examples/cross-sparc32_config.xml
index 80ee00f..820b3ad 100644
--- a/config/examples/cross-sparc32_config.xml
+++ b/config/examples/cross-sparc32_config.xml
@@ -26,6 +26,7 @@
+
@@ -61,6 +62,8 @@
+
+
diff --git a/config/examples/sparc32_config.xml b/config/examples/sparc32_config.xml
index 6a3f434..f85ac12 100644
--- a/config/examples/sparc32_config.xml
+++ b/config/examples/sparc32_config.xml
@@ -61,6 +61,8 @@
+
+
diff --git a/drivers/build.xml b/drivers/build.xml
index bfa3db5..b61486b 100644
--- a/drivers/build.xml
+++ b/drivers/build.xml
@@ -8,12 +8,16 @@
+
+
+
+
diff --git a/drivers/esp.c b/drivers/esp.c
new file mode 100644
index 0000000..5fa48a8
--- /dev/null
+++ b/drivers/esp.c
@@ -0,0 +1,377 @@
+/*
+ * OpenBIOS ESP driver
+ *
+ * Copyright (C) 2004 Jens Axboe
+ * Copyright (C) 2005 Stefan Reinauer
+ *
+ * Credit goes to Hale Landis for his excellent ata demo software
+ * OF node handling and some fixes by Stefan Reinauer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2
+ *
+ */
+
+#include "openbios/config.h"
+#include "openbios/bindings.h"
+#include "openbios/kernel.h"
+#include "libc/byteorder.h"
+#include "libc/vsprintf.h"
+
+#include "openbios/drivers.h"
+#include "asm/dma.h"
+
+#define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */
+#define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */
+
+#define REGISTER_NAMED_NODE( name, path ) do { \
+ bind_new_node( name##_flags_, name##_size_, \
+ path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
+ } while(0)
+
+#define REGISTER_NODE_METHODS( name, path ) do { \
+ char *paths[1]; \
+ \
+ paths[0] = path; \
+ bind_node( name##_flags_, name##_size_, \
+ paths, 1, name##_m, sizeof(name##_m)/sizeof(method_t)); \
+ } while(0)
+
+struct esp_dma {
+ struct sparc_dma_registers *regs;
+ enum dvma_rev revision;
+};
+
+typedef struct sd_private {
+ unsigned int id;
+ unsigned int hw_sector;
+} sd_private_t;
+
+struct esp_regs {
+ unsigned int regs[16];
+};
+
+typedef struct esp_private {
+ volatile struct esp_regs *ll;
+ __u32 buffer_dvma;
+ unsigned int irq; /* device IRQ number */
+
+ struct esp_dma *espdma; /* If set this points to espdma */
+
+ unsigned char *buffer;
+} esp_private_t;
+
+/* DECLARE data structures for the nodes. */
+DECLARE_UNNAMED_NODE(ob_sd, INSTALL_OPEN, sizeof(sd_private_t));
+DECLARE_UNNAMED_NODE(ob_esp, INSTALL_OPEN, sizeof(esp_private_t));
+
+// offset is multiple of 512, len in bytes
+static int
+ob_sd_read_sectors(sd_private_t *sd, int offset, void *dest, short len)
+{
+#if 0
+ unsigned char *buffer = malloc(2048); // XXX setup dvma
+
+ // Set SCSI target
+ outb(PHYS_JJ_ESP + 4*4, sd->id & 7);
+ // Set DMA address
+ outl(PHYS_JJ_ESPDMA + 4, buffer);
+ // Set DMA length
+ outb(PHYS_JJ_ESP + 0*4, 10);
+ outb(PHYS_JJ_ESP + 1*4, 0);
+ // Set DMA direction
+ outl(PHYS_JJ_ESPDMA + 0, 0x000);
+ // Setup command = Read(10)
+ buffer[0] = 0x80;
+ buffer[1] = 0x28;
+ buffer[2] = 0x00;
+ buffer[3] = (offset >> 24) & 0xff;
+ buffer[4] = (offset >> 16) & 0xff;
+ buffer[5] = (offset >> 8) & 0xff;
+ buffer[6] = offset & 0xff;
+ buffer[7] = 0x00;
+ buffer[8] = ((len / 512) >> 8) & 0xff;
+ buffer[9] = (len / 512) & 0xff;
+ // Set ATN, issue command
+ outb(PHYS_JJ_ESP + 3*4, 0xc2);
+
+ // Set DMA length
+ outb(PHYS_JJ_ESP + 0*4, len & 0xff);
+ outb(PHYS_JJ_ESP + 1*4, (len >> 8) & 0xff);
+ // Set DMA direction
+ outl(PHYS_JJ_ESPDMA + 0, 0x100);
+ // Transfer
+ outb(PHYS_JJ_ESP + 3*4, 0x90);
+ memcpy(buffer, dest, len);
+ free(buffer);
+#endif
+ return 0 * sd->id * offset * len * (int)dest;
+}
+
+static void
+ob_sd_read_blocks(sd_private_t *sd)
+{
+ cell n = POP(), cnt=n;
+ ucell blk = POP();
+ char *dest = (char*)POP();
+
+#ifdef CONFIG_DEBUG_ESP
+ printk("ob_sd_read_blocks %lx block=%d n=%d\n", (unsigned long)dest, blk, n );
+#endif
+ while (n) {
+ int len = n;
+
+ if (ob_sd_read_sectors(sd, blk, dest, len)) {
+ printk("ob_ide_read_blocks: error\n");
+ RET(0);
+ }
+ dest += len * sd->hw_sector;
+ n -= len;
+ blk += len;
+ }
+ PUSH(cnt);
+}
+
+static void
+ob_sd_block_size(sd_private_t *sd)
+{
+ PUSH(sd->hw_sector);
+}
+
+static unsigned int
+get_block_size(sd_private_t *sd)
+{
+#if 1
+ return 512 + sd->id * 0; // XXX
+#else
+ unsigned char *buffer = malloc(64); // XXX setup dvma
+ unsigned int ret;
+
+ // Set SCSI target
+ outb(PHYS_JJ_ESP + 4*4, sd->id & 7);
+ // Set DMA address
+ outl(PHYS_JJ_ESPDMA + 4, buffer);
+ // Set DMA length
+ outb(PHYS_JJ_ESP + 0*4, 10);
+ outb(PHYS_JJ_ESP + 1*4, 0);
+ // Set DMA direction
+ outl(PHYS_JJ_ESPDMA + 0, 0x000);
+ // Setup command = Read Capacity
+ buffer[0] = 0x80;
+ buffer[1] = 0x25;
+ buffer[2] = 0x00;
+ buffer[3] = 0x00;
+ buffer[4] = 0x00;
+ buffer[5] = 0x00;
+ buffer[6] = 0x00;
+ buffer[7] = 0x00;
+ buffer[8] = 0x00;
+ buffer[9] = 0x00;
+ buffer[10] = 0x00;
+ // Set ATN, issue command
+ outb(PHYS_JJ_ESP + 3*4, 0xc2);
+
+ // Set DMA length
+ outb(PHYS_JJ_ESP + 0*4, 0);
+ outb(PHYS_JJ_ESP + 1*4, 8 & 0xff);
+ // Set DMA direction
+ outl(PHYS_JJ_ESPDMA + 0, 0x100);
+ // Transfer
+ outb(PHYS_JJ_ESP + 3*4, 0x90);
+ ret = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
+ free(buffer);
+ return ret;
+#endif
+}
+
+static void
+ob_sd_open(sd_private_t *sd)
+{
+ int ret=1;
+ phandle_t ph;
+
+ fword("my-unit");
+ sd->id = POP();
+ sd->hw_sector = get_block_size(sd);
+
+#ifdef CONFIG_DEBUG_ESP
+ printk("opening drive %d\n", sd->id);
+#endif
+
+#if 0
+ dump_drive(drive);
+
+ if (drive->type != esp_type_ata)
+ ret= !ob_esp_atapi_drive_ready(drive);
+#endif
+
+ selfword("open-deblocker");
+
+ /* interpose disk-label */
+ ph = find_dev("/packages/disk-label");
+ fword("my-args");
+ PUSH_ph( ph );
+ fword("interpose");
+
+ RET ( -ret );
+}
+
+static void
+ob_sd_close(__attribute__((unused)) sd_private_t *sd)
+{
+ selfword("close-deblocker");
+}
+
+NODE_METHODS(ob_sd) = {
+ { "open", ob_sd_open },
+ { "close", ob_sd_close },
+ { "read-blocks", ob_sd_read_blocks },
+ { "block-size", ob_sd_block_size },
+};
+
+static void
+ob_esp_initialize(esp_private_t *esp)
+{
+ phandle_t ph=get_cur_dev();
+
+ set_int_property(ph, "#address-cells", 2);
+ set_int_property(ph, "#size-cells", 0);
+
+ /* set device type */
+ push_str("scsi");
+ fword("device-type");
+
+ /* set reg */
+ PUSH(4);
+ fword("encode-int");
+ PUSH(0x08800000);
+ fword("encode-int");
+ fword("encode+");
+ PUSH(0x00000010);
+ fword("encode-int");
+ fword("encode+");
+ push_str("reg");
+ fword("property");
+#if 1
+ esp->ll = (void *)PHYS_JJ_ESP;
+ esp->buffer = (void *)0x100000; // XXX
+#else
+ /* Get the IO region */
+ esp->ll = map_io(PHYS_JJ_ESP, sizeof (struct esp_regs));
+ if (esp->ll == 0)
+ return -1;
+
+ esp->buffer = dvma_alloc(BUFSIZE, &esp->buffer_dvma);
+ esp->espdma = espdma;
+#endif
+ // Chip reset
+ outb((int)esp->ll + 3*2, 2);
+}
+
+static void
+ob_esp_decodeunit(__attribute__((unused)) esp_private_t * esp)
+{
+ fword("decode-unit-scsi");
+}
+
+
+static void
+ob_esp_encodeunit(__attribute__((unused)) esp_private_t * esp)
+{
+ fword("encode-unit-scsi");
+}
+
+NODE_METHODS(ob_esp) = {
+ { NULL, ob_esp_initialize },
+ { "decode-unit", ob_esp_decodeunit },
+ { "encode-unit", ob_esp_encodeunit },
+};
+
+static int
+drive_present(int drive)
+{
+ // XXX
+ if (drive == 0 || drive == 2)
+ return 1;
+ return 0;
+}
+
+static int
+drive_cdrom(int drive)
+{
+ // XXX
+ if (drive == 2)
+ return 1;
+ return 0;
+}
+
+static void
+add_alias(const unsigned char *device, const unsigned char *alias)
+{
+ push_str("/aliases");
+ fword("find-device");
+ push_str(device);
+ fword("encode-string");
+ push_str(alias);
+ fword("encode-string");
+ fword("property");
+}
+
+int ob_esp_init(void)
+{
+ int id, diskcount = 0, cdcount = 0, *counter_ptr;
+ char nodebuff[256], aliasbuff[256];
+ const char *type;
+
+#ifdef CONFIG_DEBUG_ESP
+ printk("Initializing SCSI...");
+#endif
+ sprintf(nodebuff, "/iommu/sbus/espdma/esp");
+ REGISTER_NAMED_NODE(ob_esp, nodebuff);
+ device_end();
+#ifdef CONFIG_DEBUG_ESP
+ printk("done\n");
+ printk("Initializing SCSI devices...");
+#endif
+ for (id = 0; id < 8; id++) {
+ if (!drive_present(id))
+ continue;
+ push_str("/iommu/sbus/espdma/esp");
+ fword("find-device");
+ fword("new-device");
+ push_str("sd");
+ fword("device-name");
+ push_str("block");
+ fword("device-type");
+ fword("is-deblocker");
+ PUSH(id);
+ fword("encode-int");
+ PUSH(0);
+ fword("encode-int");
+ fword("encode+");
+ push_str("reg");
+ fword("property");
+ fword("finish-device");
+ sprintf(nodebuff, "/iommu/sbus/espdma/esp/sd@%d,0", id);
+ REGISTER_NODE_METHODS(ob_sd, nodebuff);
+ if (drive_cdrom(id)) {
+ type = "cdrom";
+ counter_ptr = &cdcount;
+ } else {
+ type = "disk";
+ counter_ptr = &diskcount;
+ }
+ if (*counter_ptr == 0) {
+ add_alias(nodebuff, type);
+ }
+ sprintf(aliasbuff, "%s%d", type, *counter_ptr);
+ (*counter_ptr)++;
+ add_alias(nodebuff, aliasbuff);
+ }
+#ifdef CONFIG_DEBUG_ESP
+ printk("done\n");
+#endif
+
+ return 0;
+}
diff --git a/drivers/esp.fs b/drivers/esp.fs
new file mode 100644
index 0000000..9e37c0a
--- /dev/null
+++ b/drivers/esp.fs
@@ -0,0 +1,18 @@
+\ -------------------------------------------------------------------------
+\ SCSI encode/decode unit
+\ -------------------------------------------------------------------------
+
+: decode-unit-scsi ( str len -- id lun )
+ ascii , left-split
+ ( addr-R len-R addr-L len-L )
+ parse-hex
+ -rot parse-hex
+ swap
+;
+
+: encode-unit-scsi ( id lun -- str len)
+ swap
+ pocket tohexstr
+ " ," pocket tmpstrcat >r
+ rot pocket tohexstr r> tmpstrcat drop
+;
diff --git a/drivers/sbus.c b/drivers/sbus.c
new file mode 100644
index 0000000..ba2c30b
--- /dev/null
+++ b/drivers/sbus.c
@@ -0,0 +1,52 @@
+/*
+ * OpenBIOS SBus driver
+ *
+ * (C) 2004 Stefan Reinauer
+ * (C) 2005 Ed Schouten
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2
+ *
+ */
+
+#include "openbios/config.h"
+#include "openbios/bindings.h"
+#include "openbios/kernel.h"
+#include "libc/byteorder.h"
+#include "libc/vsprintf.h"
+
+#include "openbios/drivers.h"
+
+static void
+ob_sbus_open(int *idx)
+{
+ int ret=1;
+ RET ( -ret );
+}
+
+static void
+ob_sbus_close(int *idx)
+{
+ selfword("close-deblocker");
+}
+
+static void
+ob_sbus_initialize(int *idx)
+{
+}
+
+
+NODE_METHODS(ob_sbus_node) = {
+ { NULL, ob_sbus_initialize },
+ { "open", ob_sbus_open },
+ { "close", ob_sbus_close },
+};
+
+
+int ob_sbus_init(void)
+{
+ printk("Initializing SBus devices...\n");
+
+ return 0;
+}
diff --git a/drivers/sbus.fs b/drivers/sbus.fs
new file mode 100644
index 0000000..2097fa8
--- /dev/null
+++ b/drivers/sbus.fs
@@ -0,0 +1,19 @@
+\ -------------------------------------------------------------------------
+\ SBus encode/decode unit
+\ -------------------------------------------------------------------------
+
+: decode-unit-sbus ( str len -- id lun )
+ ascii , left-split
+ ( addr-R len-R addr-L len-L )
+ parse-hex
+ -rot parse-hex
+ swap
+;
+
+: encode-unit-sbus ( id lun -- str len)
+ swap
+ pocket tohexstr
+ " ," pocket tmpstrcat >r
+ rot pocket tohexstr r> tmpstrcat drop
+;
+
diff --git a/include/openbios/drivers.h b/include/openbios/drivers.h
index a40af0a..f34385e 100644
--- a/include/openbios/drivers.h
+++ b/include/openbios/drivers.h
@@ -14,7 +14,13 @@
#ifdef CONFIG_DRIVER_PCI
int ob_pci_init(void);
#endif
+#ifdef CONFIG_DRIVER_SBUS
+int ob_sbus_init(void);
+#endif
#ifdef CONFIG_DRIVER_IDE
int ob_ide_init(void);
#endif
+#ifdef CONFIG_DRIVER_ESP
+int ob_esp_init(void);
+#endif
diff --git a/include/sparc32/dma.h b/include/sparc32/dma.h
new file mode 100644
index 0000000..e131055
--- /dev/null
+++ b/include/sparc32/dma.h
@@ -0,0 +1,213 @@
+/*
+ * Local copy of include/asm-sparc/dma.h
+ *
+ * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _ASM_SPARC_DMA_H
+#define _ASM_SPARC_DMA_H
+
+/* #include */
+/* #include */
+typedef unsigned int __u32;
+
+/* These are irrelevant for Sparc DMA, but we leave it in so that
+ * things can compile.
+ */
+#define MAX_DMA_CHANNELS 8
+#define MAX_DMA_ADDRESS (~0UL)
+#define DMA_MODE_READ 1
+#define DMA_MODE_WRITE 2
+
+/* Useful constants */
+#define SIZE_16MB (16*1024*1024)
+#define SIZE_64K (64*1024)
+
+/* Structure to describe the current status of DMA registers on the Sparc */
+struct sparc_dma_registers {
+ __volatile__ __u32 cond_reg; /* DMA condition register */
+ __volatile__ __u32 st_addr; /* Start address of this transfer */
+ __volatile__ __u32 cnt; /* How many bytes to transfer */
+ __volatile__ __u32 dma_test; /* DMA test register */
+};
+
+/* DVMA chip revisions */
+enum dvma_rev {
+ dvmarev0,
+ dvmaesc1,
+ dvmarev1,
+ dvmarev2,
+ dvmarev3,
+ dvmarevplus,
+ dvmahme
+};
+
+#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
+
+#if 0
+/* Linux DMA information structure, filled during probe. */
+struct Linux_SBus_DMA {
+ struct Linux_SBus_DMA *next;
+ struct linux_sbus_device *SBus_dev;
+ struct sparc_dma_registers *regs;
+
+ /* Status, misc info */
+ int node; /* Prom node for this DMA device */
+ int running; /* Are we doing DMA now? */
+ int allocated; /* Are we "owned" by anyone yet? */
+
+ /* Transfer information. */
+ unsigned long addr; /* Start address of current transfer */
+ int nbytes; /* Size of current transfer */
+ int realbytes; /* For splitting up large transfers, etc. */
+
+ /* DMA revision */
+ enum dvma_rev revision;
+};
+
+extern struct Linux_SBus_DMA *dma_chain;
+#endif
+
+/* Broken hardware... */
+/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
+ * Or is rev0 present only on sun4 boxes? -jj */
+#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
+#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
+
+/* Fields in the cond_reg register */
+/* First, the version identification bits */
+#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
+#define DMA_VERS0 0x00000000 /* Sunray DMA version */
+#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
+#define DMA_VERS1 0x80000000 /* DMA rev 1 */
+#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
+#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
+#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
+
+#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
+#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
+#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
+#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
+#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
+#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
+#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
+#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
+#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
+#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
+#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
+#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
+#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
+#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
+#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
+#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
+#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
+#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
+#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
+#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
+#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
+#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
+#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */
+#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
+#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
+#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
+#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
+#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
+#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
+#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
+#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
+#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
+#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
+#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
+#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
+#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
+#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
+#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
+#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
+
+/* Values describing the burst-size property from the PROM */
+#define DMA_BURST1 0x01
+#define DMA_BURST2 0x02
+#define DMA_BURST4 0x04
+#define DMA_BURST8 0x08
+#define DMA_BURST16 0x10
+#define DMA_BURST32 0x20
+#define DMA_BURST64 0x40
+#define DMA_BURSTBITS 0x7f
+
+/* Determine highest possible final transfer address given a base */
+#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
+
+/* Yes, I hack a lot of elisp in my spare time... */
+#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR))
+#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
+#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE))
+#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE)))
+#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
+#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
+#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
+#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr))
+#define DMA_BEGINDMA_W(regs) \
+ ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
+#define DMA_BEGINDMA_R(regs) \
+ ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
+
+#if 0
+
+/* For certain DMA chips, we need to disable ints upon irq entry
+ * and turn them back on when we are done. So in any ESP interrupt
+ * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
+ * when leaving the handler. You have been warned...
+ */
+#define DMA_IRQ_ENTRY(dma, dregs) do { \
+ if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
+ } while (0)
+
+#define DMA_IRQ_EXIT(dma, dregs) do { \
+ if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
+ } while(0)
+
+
+/* Pause until counter runs out or BIT isn't set in the DMA condition
+ * register.
+ */
+extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
+ unsigned long bit)
+{
+ int ctr = 50000; /* Let's find some bugs ;) */
+
+ /* Busy wait until the bit is not set any more */
+ while((regs->cond_reg&bit) && (ctr>0)) {
+ ctr--;
+ __delay(5);
+ }
+
+ /* Check for bogus outcome. */
+ if(!ctr)
+ panic("DMA timeout");
+}
+
+/* Reset the friggin' thing... */
+#define DMA_RESET(dma) do { \
+ struct sparc_dma_registers *regs = dma->regs; \
+ /* Let the current FIFO drain itself */ \
+ sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \
+ /* Reset the logic */ \
+ regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \
+ __delay(400); /* let the bits set ;) */ \
+ regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \
+ sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \
+ /* Enable FAST transfers if available */ \
+ if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \
+ dma->running = 0; \
+} while(0)
+
+#define for_each_dvma(dma) \
+ for((dma) = dma_chain; (dma); (dma) = (dma)->next)
+
+extern int get_dma_list(char *);
+extern int request_dma(unsigned int, __const__ char *);
+extern void free_dma(unsigned int);
+
+#endif
+
+#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/include/sparc32/io.h b/include/sparc32/io.h
index a3492fc..1314404 100644
--- a/include/sparc32/io.h
+++ b/include/sparc32/io.h
@@ -171,9 +171,9 @@ static inline void _outsw(volatile uint16_t * port, const void *buf,
#define inb(reg) ((u8)0xff)
#define inw(reg) ((u16)0xffff)
#define inl(reg) ((u32)0xffffffff)
-#define outb(reg, val) // nothing
-#define outw(reg, val) // nothing
-#define outl(reg, val) // nothing
+#define outb(reg, val) do{} while(0)
+#define outw(reg, val) do{} while(0)
+#define outl(reg, val) do{} while(0)
#else
extern u8 inb(u32 reg);
extern u16 inw(u32 reg);
diff --git a/kernel/dict.c b/kernel/dict.c
index b67b58c..74b475c 100644
--- a/kernel/dict.c
+++ b/kernel/dict.c
@@ -144,7 +144,10 @@ ucell load_dictionary(const char *data, ucell len)
if(checksum) {
printk("Checksum invalid (%08x)!\n", checksum);
+#ifndef __sparc__ // XXX hack
+#warn "FIXME: checksum calculation does not seem to work on SPARC32"
return 0;
+#endif
}
data += sizeof(dictionary_header_t);