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.
18 #define STR(A) _STR(A)
20 #define NAME "diag init"
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
=
38 (struct Resident
*)&rom_tag
,
45 (STRPTR
)version_string
,
50 static void debugRAM(void)
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
);
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"));
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
);
92 *out
++ = (rom
[offset
* 4 + 0] & 0xf0) | ((rom
[offset
* 4 + 2] & 0xf0) >> 4);
98 *out
++ = rom
[offset
* 2];
104 /* AOS does it this way */
105 CopyMem((void*)rom
, out
, size
);
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"));
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
128 if ((da_config
& DAC_BOOTTIME
) != DAC_CONFIGTIME
)
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
))
139 da
= AllocMem(datmp
.da_Size
, MEMF_PUBLIC
);
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
);)
153 static void callroms(struct ExpansionBase
*ExpansionBase
)
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
)
180 struct ExpansionBase
*eb
= (struct ExpansionBase
*)FindName(&SysBase
->LibList
, "expansion.library");
182 Alert(AT_DeadEnd
| AO_ExpansionLib
);
184 eb
->eb_Private2
[0] = (IPTR
)SysBase
;
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)