Support non-MEMF_KICK fast ram boards (Blizzard A1200 accelerators) in arosbootstrap...
[AROS.git] / arch / m68k-amiga / diag / diag.c
blob0640d568cc63e5201302b6a03ab9c95b5ddd427a
2 #define DEBUG 1
4 #include <aros/debug.h>
5 #include <exec/types.h>
6 #include <exec/resident.h>
7 #include <proto/expansion.h>
8 #include <aros/asmcall.h>
9 #include <libraries/expansionbase.h>
10 #include <libraries/configvars.h>
11 #include <libraries/configregs.h>
13 /* This is first RTF_COLDSTART resident.
14 * Update eb_SysBase, call DAC_CONFIGTIME.
17 #define _STR(A) #A
18 #define STR(A) _STR(A)
20 #define NAME "diag init"
21 #define VERSION 41
22 #define REVISION 1
24 static AROS_UFP3 (APTR, Init,
25 AROS_UFPA(struct Library *, lh, D0),
26 AROS_UFPA(BPTR, segList, A0),
27 AROS_UFPA(struct ExecBase *, sysBase, A6));
29 static const TEXT name_string[] = NAME;
30 static const TEXT version_string[] =
31 NAME " " STR(VERSION) "." STR(REVISION) " " ADATE "\n";
33 extern void diag_end(void);
35 const struct Resident rom_tag =
37 RTC_MATCHWORD,
38 (struct Resident *)&rom_tag,
39 (APTR)&diag_end,
40 RTF_COLDSTART,
41 VERSION,
42 NT_UNKNOWN,
43 105,
44 (STRPTR)name_string,
45 (STRPTR)version_string,
46 (APTR)Init
50 static void debugRAM(void)
52 struct MemHeader *mh;
53 ForeachNode(&SysBase->MemList, mh) {
54 bug("%08x: %08x - %08x %08x %d '%s'\n",
55 mh, mh->mh_Lower, mh->mh_Upper, mh->mh_Attributes,
56 mh->mh_Node.ln_Pri, mh->mh_Node.ln_Name ? mh->mh_Node.ln_Name : "<null>");
61 static BOOL calldiagrom(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
63 struct DiagArea *diag = configDev->cd_Rom.er_DiagArea;
64 UWORD offset = diag->da_DiagPoint;
65 APTR code = (APTR)(((UBYTE*)diag) + offset);
66 ULONG ret;
68 // call autoconfig ROM da_DiagPoint
69 D(bug("Call boot rom @%p board %p diag %p configdev %p\n",
70 code, configDev->cd_BoardAddr, diag, configDev));
71 ret = AROS_UFC5(ULONG, code,
72 AROS_UFCA(APTR, configDev->cd_BoardAddr, A0),
73 AROS_UFCA(struct DiagArea*, diag, A2),
74 AROS_UFCA(struct ConfigDev*, configDev, A3),
75 AROS_UFCA(struct ExpansionBase*, ExpansionBase, A5),
76 AROS_UFCA(struct ExecBase*, SysBase, A6));
77 D(bug(ret ? "->success\n" : "->failed\n"));
78 return ret != 0;
82 // read one byte from expansion autoconfig ROM
83 static void copyromdata(struct ConfigDev *configDev, UBYTE buswidth, UWORD size, UBYTE *out)
85 volatile UBYTE *rom = (UBYTE*)(configDev->cd_BoardAddr + configDev->cd_Rom.er_InitDiagVec);
86 UWORD offset = 0;
88 switch (buswidth)
90 case DAC_NIBBLEWIDE:
91 while (size-- > 0) {
92 *out++ = (rom[offset * 4 + 0] & 0xf0) | ((rom[offset * 4 + 2] & 0xf0) >> 4);
93 offset++;
95 break;
96 case DAC_BYTEWIDE:
97 while (size-- > 0) {
98 *out++ = rom[offset * 2];
99 offset++;
101 break;
102 case DAC_WORDWIDE:
103 default:
104 /* AOS does it this way */
105 CopyMem((void*)rom, out, size);
106 break;
110 static BOOL diagrom(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
112 struct DiagArea *da, datmp;
113 UBYTE da_config, buswidth;
115 D(bug("Read boot ROM base=%p cd=%p type=%02x\n", configDev->cd_BoardAddr, configDev, configDev->cd_Rom.er_Type));
117 if (!(configDev->cd_Rom.er_Type & ERTF_DIAGVALID) || !configDev->cd_Rom.er_InitDiagVec) {
118 D(bug("Board without boot ROM\n"));
119 return FALSE;
122 copyromdata(configDev, DAC_BYTEWIDE, 1, &da_config);
123 /* NOTE: lower nibble may not be valid if actual bus type is not BYTEWIDE */
124 D(bug("da_Config=%02x\n", da_config & 0xf0));
125 buswidth = da_config & DAC_BUSWIDTH;
126 if (buswidth == DAC_BUSWIDTH) // illegal
127 return FALSE;
128 if ((da_config & DAC_BOOTTIME) != DAC_CONFIGTIME)
129 return FALSE;
131 // read DiagArea only
132 copyromdata(configDev, buswidth, sizeof(struct DiagArea), (UBYTE*)&datmp);
134 D(bug("Size=%04x DiagPoint=%04x BootPoint=%04x Name=%04x\n",
135 datmp.da_Size, datmp.da_DiagPoint, datmp.da_BootPoint, datmp.da_Name));
136 if (datmp.da_Size < sizeof (struct DiagArea))
137 return FALSE;
139 da = AllocMem(datmp.da_Size, MEMF_PUBLIC);
140 if (!da)
141 return FALSE;
143 configDev->cd_Rom.er_DiagArea = da;
144 // read rom data, DiagArea is also copied again. AOS compatibility!
145 copyromdata(configDev, buswidth, datmp.da_Size, (UBYTE*)da);
147 D(if (da->da_Name != 0 && da->da_Name != 0xffff && da->da_Name < da->da_Size)
148 bug("Name='%s'\n", (UBYTE*)da + da->da_Name);)
150 return TRUE;
153 static void callroms(struct ExpansionBase *ExpansionBase)
155 struct Node *node;
156 D(bug("callroms\n"));
157 ForeachNode(&ExpansionBase->BoardList, node) {
158 struct ConfigDev *configDev = (struct ConfigDev*)node;
159 if (diagrom(ExpansionBase, configDev)) {
160 if (!calldiagrom(ExpansionBase, configDev)) {
161 FreeMem(configDev->cd_Rom.er_DiagArea, configDev->cd_Rom.er_DiagArea->da_Size);
162 configDev->cd_Rom.er_DiagArea = NULL;
166 D(bug("callroms done\n"));
170 void InitKickMemDiag(void);
172 static AROS_UFH3 (APTR, Init,
173 AROS_UFHA(struct Library *, lh, D0),
174 AROS_UFHA(BPTR, segList, A0),
175 AROS_UFHA(struct ExecBase *, SysBase, A6)
178 AROS_USERFUNC_INIT
180 struct ExpansionBase *eb = (struct ExpansionBase*)FindName(&SysBase->LibList, "expansion.library");
181 if (!eb)
182 Alert(AT_DeadEnd | AO_ExpansionLib);
184 eb->eb_Private2[0] = (IPTR)SysBase;
186 callroms(eb);
188 D(debugRAM());
190 /* ArosBootStrap mode? Check for kick modules again if some of our kick modules
191 * are located in diag initialized ram (Blizzard A1200 accelerator boards)
193 InitKickMemDiag();
195 AROS_USERFUNC_EXIT
197 return NULL;