Use rom_init.S memory test routine to detect size of autosize autoconfig ram boards.
[AROS.git] / arch / m68k-amiga / expansion / configchain.c
blob8390f18d0cf7194af073a1e9334fc8e0d44211e5
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <proto/expansion.h>
14 #include "expansion_intern.h"
16 #include <clib/expansion_protos.h>
17 #include <proto/exec.h>
18 #include <exec/resident.h>
19 #include <aros/asmcall.h>
21 // ROMTAG INIT time
22 static void romtaginit(struct ExpansionBase *ExpansionBase)
24 struct Node *node;
25 // look for possible romtags in expansion ROM image and InitResident() them if found
26 D(bug("romtaginit\n"));
27 ForeachNode(&IntExpBase(ExpansionBase)->eb_BoardList, node) {
28 struct ConfigDev *configDev = (struct ConfigDev*)node;
29 if (configDev->cd_Rom.er_DiagArea && (configDev->cd_Rom.er_DiagArea->da_Config & DAC_BOOTTIME) == DAC_CONFIGTIME) {
30 struct Resident *res;
31 UWORD *romptr = (UWORD*)configDev->cd_Rom.er_DiagArea;
32 UWORD *romend = (UWORD*)(((UBYTE*)configDev->cd_Rom.er_DiagArea) + configDev->cd_Rom.er_DiagArea->da_Size);
33 SetCurrentBinding(&configDev, 4);
34 while (romptr < romend - sizeof (struct Resident*)) {
35 res = (struct Resident*)romptr;
36 if (res->rt_MatchWord == RTC_MATCHWORD && res->rt_MatchTag == res && res->rt_Pri < 105) {
37 D(bug("initresident %x '%s'\n", res, res->rt_Name));
38 InitResident(res, NULL);
39 romptr += 13; //sizeof (struct Resident);
40 } else {
41 romptr += 1;
48 extern UBYTE _rom_start;
49 extern UBYTE _ext_start;
51 static ULONG checkramrom(UBYTE *addr, ULONG size, ULONG mask)
53 /* check if our "rom" is loaded to ram */
54 if (addr < &_rom_start && addr + size > &_rom_start)
55 size = (&_rom_start - addr) & ~mask;
56 return size;
59 AROS_UFP3(ULONG, MemoryTest,
60 AROS_UFPA(APTR, startaddr, A0),
61 AROS_UFPA(APTR, endaddr, A1),
62 AROS_UFPA(ULONG, block, D0));
64 static ULONG autosize(struct ExpansionBase *ExpansionBase, struct ConfigDev *configDev)
66 UBYTE sizebits = configDev->cd_Rom.er_Flags & ERT_Z3_SSMASK;
67 ULONG maxsize = configDev->cd_BoardSize;
68 ULONG size = 0;
69 UBYTE *addr = (UBYTE*)configDev->cd_BoardAddr;
71 D(bug("sizebits=%x\n", sizebits));
72 if (sizebits >= 14) /* 14 and 15 = reserved */
73 return 0;
74 if (sizebits >= 2 && sizebits <= 8)
75 return 0x00010000 << (sizebits - 2);
76 if (sizebits >= 9)
77 return 0x00600000 + (0x200000 * (sizebits - 9));
78 maxsize = checkramrom(addr, maxsize, 0x7ffff);
79 if (!maxsize)
80 return 0;
81 size = AROS_UFC3(ULONG, MemoryTest,
82 AROS_UFCA(APTR, addr, A0),
83 AROS_UFCA(APTR, addr + maxsize, A1),
84 AROS_UFCA(ULONG, 0x80000, D0));
85 D(bug("size=%x maxsize=%x\n", size, maxsize));
86 return size;
89 static void allocram(struct ExpansionBase *ExpansionBase)
91 struct Node *node;
93 // we should merge address spaces, later..
94 D(bug("adding ram boards\n"));
95 ForeachNode(&IntExpBase(ExpansionBase)->eb_BoardList, node) {
96 struct ConfigDev *configDev = (struct ConfigDev*)node;
97 if ((configDev->cd_Rom.er_Type & ERTF_MEMLIST) && !(configDev->cd_Flags & CDF_SHUTUP) && !(configDev->cd_Flags & CDF_PROCESSED)) {
98 ULONG attr = MEMF_PUBLIC | MEMF_FAST;
99 ULONG size = configDev->cd_BoardSize;
100 APTR addr = configDev->cd_BoardAddr;
101 LONG pri = 20;
102 if (configDev->cd_BoardAddr <= (APTR)0x00FFFFFF) {
103 attr |= MEMF_24BITDMA;
104 pri = 0;
105 } else if ((configDev->cd_Rom.er_Flags & ERT_Z3_SSMASK) != 0) {
106 size = autosize(ExpansionBase, configDev);
108 if (size && size <= configDev->cd_BoardSize) {
109 size = checkramrom(addr, size, 65535);
110 if (size) {
111 D(bug("ram board at %08x, size %08x attr %08x\n", addr, size, attr));
112 AddMemList(size, attr, pri, addr, "Fast Memory");
115 configDev->cd_Flags |= CDF_PROCESSED;
118 D(bug("ram boards done\n"));
122 AROS_LH1(void, ConfigChain,
123 AROS_LHA(APTR, baseAddr, A0),
124 struct ExpansionBase *, ExpansionBase, 11, Expansion)
126 AROS_LIBFUNC_INIT
128 struct ConfigDev *configDev = NULL;
130 if (baseAddr == 0) {
131 // called by strap
132 romtaginit(ExpansionBase);
133 return;
135 bug("configchain\n");
136 for(;;) {
137 if (!configDev)
138 configDev = AllocConfigDev();
139 if (!configDev)
140 break;
141 if (!ReadExpansionRom(baseAddr, configDev)) {
142 FreeConfigDev(configDev);
143 break;
145 if (ConfigBoard(baseAddr, configDev)) {
146 AddTail(&IntExpBase(ExpansionBase)->eb_BoardList, &configDev->cd_Node);
147 configDev = NULL;
151 allocram(ExpansionBase);
153 AROS_LIBFUNC_EXIT
154 } /* ConfigChain */