add place-holder directory for the a3000 wd533c93 scsi controller implementation.
[AROS.git] / arch / m68k-amiga / diag / diag.c
blobc20e57071e03530e447709921985a3da27c0c038
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
8 #include <aros/debug.h>
9 #include <exec/types.h>
10 #include <exec/resident.h>
11 #include <proto/expansion.h>
12 #include <aros/asmcall.h>
13 #include <libraries/expansionbase.h>
14 #include <libraries/configvars.h>
15 #include <libraries/configregs.h>
17 /* This is first RTF_COLDSTART resident.
18 * Update ExpansionBase->ExecBase, call DAC_CONFIGTIME.
21 #define _STR(A) #A
22 #define STR(A) _STR(A)
24 #define NAME "diag init"
25 #define VERSION 41
26 #define REVISION 1
28 static AROS_UFP3 (APTR, Init,
29 AROS_UFPA(struct Library *, lh, D0),
30 AROS_UFPA(BPTR, segList, A0),
31 AROS_UFPA(struct ExecBase *, sysBase, A6));
33 static const TEXT name_string[] = NAME;
34 static const TEXT version_string[] =
35 NAME " " STR(VERSION) "." STR(REVISION) " " ADATE "\n";
37 extern void diag_end(void);
39 const struct Resident rom_tag =
41 RTC_MATCHWORD,
42 (struct Resident *)&rom_tag,
43 (APTR)&diag_end,
44 RTF_COLDSTART,
45 VERSION,
46 NT_UNKNOWN,
47 105,
48 (STRPTR)name_string,
49 (STRPTR)version_string,
50 (APTR)Init
54 static void debugRAM(void)
56 struct MemHeader *mh;
57 ForeachNode(&SysBase->MemList, mh) {
58 bug("%08x: %08x - %08x %08x %d '%s'\n",
59 mh, mh->mh_Lower, mh->mh_Upper, mh->mh_Attributes,
60 mh->mh_Node.ln_Pri, mh->mh_Node.ln_Name ? (const char *)mh->mh_Node.ln_Name : "<null>");
65 static BOOL calldiagrom(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
67 struct DiagArea *diag = configDev->cd_Rom.er_DiagArea;
68 UWORD offset = diag->da_DiagPoint;
69 APTR code = (APTR)(((UBYTE*)diag) + offset);
70 ULONG ret;
72 // call autoconfig ROM da_DiagPoint
73 D(bug("Call boot rom @%p board %p diag %p configdev %p\n",
74 code, configDev->cd_BoardAddr, diag, configDev));
75 ret = AROS_UFC6(ULONG, code,
76 AROS_UFCA(APTR, configDev->cd_BoardAddr, A0),
77 AROS_UFCA(struct DiagArea*, diag, A2),
78 AROS_UFCA(struct ConfigDev*, configDev, A3),
79 AROS_UFCA(ULONG, 0, A4), // Dummy variable. Preserve A4 because Blizzard 1260 ROM modifies it.
80 AROS_UFCA(struct ExpansionBase*, ExpansionBase, A5),
81 AROS_UFCA(struct ExecBase*, SysBase, A6));
82 D(bug(ret ? "->success\n" : "->failed\n"));
83 return ret != 0;
87 // read one byte from expansion autoconfig ROM
88 static void copyromdata(struct ConfigDev *configDev, UBYTE buswidth, UWORD size, UBYTE *out)
90 volatile UBYTE *rom = (UBYTE*)(configDev->cd_BoardAddr + configDev->cd_Rom.er_InitDiagVec);
91 UWORD offset = 0;
93 switch (buswidth)
95 case DAC_NIBBLEWIDE:
96 while (size-- > 0) {
97 *out++ = (rom[offset * 4 + 0] & 0xf0) | ((rom[offset * 4 + 2] & 0xf0) >> 4);
98 offset++;
100 break;
101 case DAC_BYTEWIDE:
102 while (size-- > 0) {
103 *out++ = rom[offset * 2];
104 offset++;
106 break;
107 case DAC_WORDWIDE:
108 default:
109 /* AOS does it this way */
110 CopyMem((void*)rom, out, size);
111 break;
115 static BOOL diagrom(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
117 struct DiagArea *da, datmp;
118 UBYTE da_config, buswidth;
120 D(bug("Read boot ROM base=%p cd=%p type=%02x\n", configDev->cd_BoardAddr, configDev, configDev->cd_Rom.er_Type));
122 if (!(configDev->cd_Rom.er_Type & ERTF_DIAGVALID) || !configDev->cd_Rom.er_InitDiagVec) {
123 D(bug("Board without boot ROM\n"));
124 return FALSE;
127 copyromdata(configDev, DAC_BYTEWIDE, 1, &da_config);
128 /* NOTE: lower nibble may not be valid if actual bus type is not BYTEWIDE */
129 D(bug("da_Config=%02x\n", da_config & 0xf0));
130 buswidth = da_config & DAC_BUSWIDTH;
131 if (buswidth == DAC_BUSWIDTH) // illegal
132 return FALSE;
133 if ((da_config & DAC_BOOTTIME) != DAC_CONFIGTIME)
134 return FALSE;
136 // read DiagArea only
137 copyromdata(configDev, buswidth, sizeof(struct DiagArea), (UBYTE*)&datmp);
139 D(bug("Size=%04x DiagPoint=%04x BootPoint=%04x Name=%04x\n",
140 datmp.da_Size, datmp.da_DiagPoint, datmp.da_BootPoint, datmp.da_Name));
141 if (datmp.da_Size < sizeof (struct DiagArea))
142 return FALSE;
144 da = AllocMem(datmp.da_Size, MEMF_PUBLIC);
145 if (!da)
146 return FALSE;
148 configDev->cd_Rom.er_DiagArea = da;
149 // read rom data, DiagArea is also copied again. AOS compatibility!
150 copyromdata(configDev, buswidth, datmp.da_Size, (UBYTE*)da);
152 D(if (da->da_Name != 0 && da->da_Name != 0xffff && da->da_Name < da->da_Size)
153 bug("Name='%s'\n", (UBYTE*)da + da->da_Name);)
155 return TRUE;
158 static void callroms(struct ExpansionBase *ExpansionBase)
160 struct Node *node;
161 D(bug("callroms\n"));
162 ForeachNode(&ExpansionBase->BoardList, node) {
163 struct ConfigDev *configDev = (struct ConfigDev*)node;
164 if (diagrom(ExpansionBase, configDev)) {
165 if (!calldiagrom(ExpansionBase, configDev)) {
166 FreeMem(configDev->cd_Rom.er_DiagArea, configDev->cd_Rom.er_DiagArea->da_Size);
167 configDev->cd_Rom.er_DiagArea = NULL;
171 D(bug("callroms done\n"));
175 void InitKickMemDiag(struct ExecBase *SysBase);
177 static AROS_UFH3 (APTR, Init,
178 AROS_UFHA(struct Library *, lh, D0),
179 AROS_UFHA(BPTR, segList, A0),
180 AROS_UFHA(struct ExecBase *, SysBase, A6)
183 AROS_USERFUNC_INIT
185 struct ExpansionBase *eb = (struct ExpansionBase*)FindName(&SysBase->LibList, "expansion.library");
186 if (!eb)
187 Alert(AT_DeadEnd | AO_ExpansionLib);
189 eb->eb_Private02 = (IPTR)SysBase;
191 callroms(eb);
193 D(debugRAM());
195 /* ArosBootStrap mode? Check for kick modules again if some of our kick modules
196 * are located in diag initialized ram (Blizzard A1200 accelerator boards)
198 InitKickMemDiag(SysBase);
200 AROS_USERFUNC_EXIT
202 return NULL;