mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
more of the sparc32 port by Blue Swirl <blueswir1@hotmail.com>
git-svn-id: svn://coreboot.org/openbios/openbios-devel@4 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
2
Makefile
2
Makefile
@@ -10,6 +10,7 @@ info:
|
||||
clean:
|
||||
@echo -n "Cleaning up..."
|
||||
@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
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<build condition="SPARC32">
|
||||
|
||||
<include href="libgcc/build.xml"/>
|
||||
|
||||
<dictionary name="openbios-sparc32" init="openbios">
|
||||
<object source="tree.fs" target="forth"/>
|
||||
<object source="init.fs" target="forth"/>
|
||||
</dictionary>
|
||||
|
||||
@@ -11,6 +14,7 @@
|
||||
<object source="boot.c"/>
|
||||
<object source="context.c"/>
|
||||
<object source="switch.S"/>
|
||||
<object source="udiv.S"/>
|
||||
<object source="linux_load.c"/>
|
||||
<object source="sys_info.c"/>
|
||||
<object source="elfload.c"/>
|
||||
@@ -18,40 +22,53 @@
|
||||
<object source="loadfs.c"/>
|
||||
</library>
|
||||
|
||||
<executable name="target/arch/sparc32/entry.o" target="target">
|
||||
<rule><![CDATA[
|
||||
$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/sparc32/entry.S
|
||||
]]></rule>
|
||||
</executable>
|
||||
<executable name="target/arch/sparc32/vectors.o" target="target">
|
||||
<rule><![CDATA[
|
||||
$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/sparc32/vectors.S
|
||||
]]></rule>
|
||||
</executable>
|
||||
|
||||
<executable name="openbios.multiboot" target="target" condition="IMAGE_ELF_MULTIBOOT">
|
||||
<rule>
|
||||
$(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) $@
|
||||
</rule>
|
||||
<object source="multiboot.c"/>
|
||||
<object source="entry.S"/>
|
||||
<object source="vectors.S"/>
|
||||
<external-object source="target/arch/sparc32/vectors.o"/>
|
||||
<external-object source="target/arch/sparc32/entry.o"/>
|
||||
<external-object source="libsparc32.a"/>
|
||||
<external-object source="libbootstrap.a"/>
|
||||
<external-object source="libmodules.a"/>
|
||||
<external-object source="libdrivers.a"/>
|
||||
<external-object source="liblibc.a"/>
|
||||
<external-object source="libfs.a"/>
|
||||
<external-object source="libgcc.a"/>
|
||||
</executable>
|
||||
|
||||
<executable name="openbios-plain.elf" target="target" condition="IMAGE_ELF">
|
||||
<rule>
|
||||
$(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) $@
|
||||
</rule>
|
||||
<object source="plainboot.c"/>
|
||||
<object source="entry.S"/>
|
||||
<object source="vectors.S"/>
|
||||
<external-object source="target/arch/sparc32/vectors.o"/>
|
||||
<external-object source="target/arch/sparc32/entry.o"/>
|
||||
<external-object source="libsparc32.a"/>
|
||||
<external-object source="libbootstrap.a"/>
|
||||
<external-object source="libmodules.a"/>
|
||||
<external-object source="libdrivers.a"/>
|
||||
<external-object source="liblibc.a"/>
|
||||
<external-object source="libfs.a"/>
|
||||
<external-object source="libgcc.a"/>
|
||||
</executable>
|
||||
|
||||
<!-- HACK ALERT -->
|
||||
@@ -77,13 +94,13 @@
|
||||
|
||||
<executable name="openbios-builtin.elf" target="target" condition="IMAGE_ELF_EMBEDDED">
|
||||
<rule>
|
||||
$(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) $@
|
||||
</rule>
|
||||
<object source="entry.S"/>
|
||||
<object source="vectors.S"/>
|
||||
<external-object source="target/arch/sparc32/vectors.o"/>
|
||||
<external-object source="target/arch/sparc32/entry.o"/>
|
||||
<external-object source="target/arch/sparc32/builtin.o"/>
|
||||
<external-object source="libsparc32.a"/>
|
||||
<external-object source="libbootstrap.a"/>
|
||||
@@ -91,6 +108,7 @@
|
||||
<external-object source="libdrivers.a"/>
|
||||
<external-object source="liblibc.a"/>
|
||||
<external-object source="libfs.a"/>
|
||||
<external-object source="libgcc.a"/>
|
||||
</executable>
|
||||
|
||||
</build>
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
29
arch/sparc32/libgcc/__divdi3.c
Normal file
29
arch/sparc32/libgcc/__divdi3.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* arch/i386/libgcc/__divdi3.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
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;
|
||||
}
|
||||
13
arch/sparc32/libgcc/__udivdi3.c
Normal file
13
arch/sparc32/libgcc/__udivdi3.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* arch/i386/libgcc/__divdi3.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
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);
|
||||
}
|
||||
33
arch/sparc32/libgcc/__udivmoddi4.c
Normal file
33
arch/sparc32/libgcc/__udivmoddi4.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
16
arch/sparc32/libgcc/__umoddi3.c
Normal file
16
arch/sparc32/libgcc/__umoddi3.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* arch/i386/libgcc/__umoddi3.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
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;
|
||||
}
|
||||
62
arch/sparc32/libgcc/ashldi3.c
Normal file
62
arch/sparc32/libgcc/ashldi3.c
Normal file
@@ -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;
|
||||
}
|
||||
63
arch/sparc32/libgcc/ashrdi3.c
Normal file
63
arch/sparc32/libgcc/ashrdi3.c
Normal file
@@ -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;
|
||||
}
|
||||
12
arch/sparc32/libgcc/build.xml
Normal file
12
arch/sparc32/libgcc/build.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<build condition="SPARC32">
|
||||
|
||||
<library name="gcc" type="static" target="target">
|
||||
<object source="ashldi3.c"/>
|
||||
<object source="ashrdi3.c"/>
|
||||
<object source="__divdi3.c"/>
|
||||
<object source="__udivdi3.c"/>
|
||||
<object source="__udivmoddi4.c"/>
|
||||
<object source="__umoddi3.c"/>
|
||||
</library>
|
||||
|
||||
</build>
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
234
arch/sparc32/tree.fs
Normal file
234
arch/sparc32/tree.fs
Normal file
@@ -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
|
||||
@@ -26,6 +26,7 @@
|
||||
<option name="CONFIG_DEBUG_INTERPRETER" type="boolean" value="false"/>
|
||||
<option name="CONFIG_DEBUG_CONSOLE" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DEBUG_CONSOLE_SERIAL" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DEBUG_ESP" type="boolean" value="true"/>
|
||||
<option name="CONFIG_SERIAL_PORT" type="integer" value="0"/>
|
||||
<option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
|
||||
|
||||
@@ -61,6 +62,8 @@
|
||||
<option name="CONFIG_LINUXBIOS" type="boolean" value="false"/>
|
||||
|
||||
<!-- Drivers -->
|
||||
<option name="CONFIG_DRIVER_SBUS" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_ESP" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="false"/>
|
||||
|
||||
</config>
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
<option name="CONFIG_LINUXBIOS" type="boolean" value="false"/>
|
||||
|
||||
<!-- Drivers -->
|
||||
<option name="CONFIG_DRIVER_SBUS" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_ESP" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="false"/>
|
||||
|
||||
</config>
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
<object source="adb.c" condition="DRIVER_ADB"/>
|
||||
<object source="cuda.c" condition="DRIVER_ADB"/>
|
||||
<object source="floppy.c" condition="DRIVER_FLOPPY"/>
|
||||
<object source="sbus.c" condition="DRIVER_SBUS"/>
|
||||
<object source="esp.c" condition="DRIVER_ESP"/>
|
||||
</library>
|
||||
|
||||
<dictionary name="openbios" target="forth">
|
||||
<object source="pci.fs" condition="DRIVER_PCI"/>
|
||||
<object source="ide.fs" condition="DRIVER_IDE"/>
|
||||
<object source="adb.fs" condition="DRIVER_ADB"/>
|
||||
<object source="sbus.fs" condition="DRIVER_SBUS"/>
|
||||
<object source="esp.fs" condition="DRIVER_ESP"/>
|
||||
</dictionary>
|
||||
|
||||
</build>
|
||||
|
||||
377
drivers/esp.c
Normal file
377
drivers/esp.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* OpenBIOS ESP driver
|
||||
*
|
||||
* Copyright (C) 2004 Jens Axboe <axboe@suse.de>
|
||||
* Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
18
drivers/esp.fs
Normal file
18
drivers/esp.fs
Normal file
@@ -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
|
||||
;
|
||||
52
drivers/sbus.c
Normal file
52
drivers/sbus.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* OpenBIOS SBus driver
|
||||
*
|
||||
* (C) 2004 Stefan Reinauer <stepan@openbios.org>
|
||||
* (C) 2005 Ed Schouten <ed@fxq.nl>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
19
drivers/sbus.fs
Normal file
19
drivers/sbus.fs
Normal file
@@ -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
|
||||
;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
213
include/sparc32/dma.h
Normal file
213
include/sparc32/dma.h
Normal file
@@ -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 <linux/kernel.h> */
|
||||
/* #include <linux/types.h> */
|
||||
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) */
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user