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:
Stefan Reinauer
2006-05-04 22:07:30 +00:00
parent 9a04f5a6c1
commit 8e89ccf89e
26 changed files with 1201 additions and 56 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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
*

View File

@@ -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

View File

@@ -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

View 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;
}

View 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);
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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>

View File

@@ -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;

View File

@@ -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
View 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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View 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
View 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
View 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
View 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
;

View File

@@ -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
View 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) */

View File

@@ -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);

View File

@@ -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);