Made field names in public and private ExpansionBases more
[AROS.git] / arch / m68k-amiga / diag / diag.c
blobdc76ab5a48500d1c7372d3ef3a94ce983e93ecc3
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 ? 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_UFC5(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(struct ExpansionBase*, ExpansionBase, A5),
80 AROS_UFCA(struct ExecBase*, SysBase, A6));
81 D(bug(ret ? "->success\n" : "->failed\n"));
82 return ret != 0;
86 // read one byte from expansion autoconfig ROM
87 static void copyromdata(struct ConfigDev *configDev, UBYTE buswidth, UWORD size, UBYTE *out)
89 volatile UBYTE *rom = (UBYTE*)(configDev->cd_BoardAddr + configDev->cd_Rom.er_InitDiagVec);
90 UWORD offset = 0;
92 switch (buswidth)
94 case DAC_NIBBLEWIDE:
95 while (size-- > 0) {
96 *out++ = (rom[offset * 4 + 0] & 0xf0) | ((rom[offset * 4 + 2] & 0xf0) >> 4);
97 offset++;
99 break;
100 case DAC_BYTEWIDE:
101 while (size-- > 0) {
102 *out++ = rom[offset * 2];
103 offset++;
105 break;
106 case DAC_WORDWIDE:
107 default:
108 /* AOS does it this way */
109 CopyMem((void*)rom, out, size);
110 break;
114 static BOOL diagrom(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
116 struct DiagArea *da, datmp;
117 UBYTE da_config, buswidth;
119 D(bug("Read boot ROM base=%p cd=%p type=%02x\n", configDev->cd_BoardAddr, configDev, configDev->cd_Rom.er_Type));
121 if (!(configDev->cd_Rom.er_Type & ERTF_DIAGVALID) || !configDev->cd_Rom.er_InitDiagVec) {
122 D(bug("Board without boot ROM\n"));
123 return FALSE;
126 copyromdata(configDev, DAC_BYTEWIDE, 1, &da_config);
127 /* NOTE: lower nibble may not be valid if actual bus type is not BYTEWIDE */
128 D(bug("da_Config=%02x\n", da_config & 0xf0));
129 buswidth = da_config & DAC_BUSWIDTH;
130 if (buswidth == DAC_BUSWIDTH) // illegal
131 return FALSE;
132 if ((da_config & DAC_BOOTTIME) != DAC_CONFIGTIME)
133 return FALSE;
135 // read DiagArea only
136 copyromdata(configDev, buswidth, sizeof(struct DiagArea), (UBYTE*)&datmp);
138 D(bug("Size=%04x DiagPoint=%04x BootPoint=%04x Name=%04x\n",
139 datmp.da_Size, datmp.da_DiagPoint, datmp.da_BootPoint, datmp.da_Name));
140 if (datmp.da_Size < sizeof (struct DiagArea))
141 return FALSE;
143 da = AllocMem(datmp.da_Size, MEMF_PUBLIC);
144 if (!da)
145 return FALSE;
147 configDev->cd_Rom.er_DiagArea = da;
148 // read rom data, DiagArea is also copied again. AOS compatibility!
149 copyromdata(configDev, buswidth, datmp.da_Size, (UBYTE*)da);
151 D(if (da->da_Name != 0 && da->da_Name != 0xffff && da->da_Name < da->da_Size)
152 bug("Name='%s'\n", (UBYTE*)da + da->da_Name);)
154 return TRUE;
157 static void callroms(struct ExpansionBase *ExpansionBase)
159 struct Node *node;
160 D(bug("callroms\n"));
161 ForeachNode(&ExpansionBase->BoardList, node) {
162 struct ConfigDev *configDev = (struct ConfigDev*)node;
163 if (diagrom(ExpansionBase, configDev)) {
164 if (!calldiagrom(ExpansionBase, configDev)) {
165 FreeMem(configDev->cd_Rom.er_DiagArea, configDev->cd_Rom.er_DiagArea->da_Size);
166 configDev->cd_Rom.er_DiagArea = NULL;
170 D(bug("callroms done\n"));
174 void InitKickMemDiag(void);
176 static AROS_UFH3 (APTR, Init,
177 AROS_UFHA(struct Library *, lh, D0),
178 AROS_UFHA(BPTR, segList, A0),
179 AROS_UFHA(struct ExecBase *, SysBase, A6)
182 AROS_USERFUNC_INIT
184 struct ExpansionBase *eb = (struct ExpansionBase*)FindName(&SysBase->LibList, "expansion.library");
185 if (!eb)
186 Alert(AT_DeadEnd | AO_ExpansionLib);
188 eb->eb_Private02 = (IPTR)SysBase;
190 callroms(eb);
192 D(debugRAM());
194 /* ArosBootStrap mode? Check for kick modules again if some of our kick modules
195 * are located in diag initialized ram (Blizzard A1200 accelerator boards)
197 InitKickMemDiag();
199 AROS_USERFUNC_EXIT
201 return NULL;