// helper functions to access pci mmio bars from real mode
-extern u32 pci_readl_32(u32 addr);
-#if MODESEGMENT == 0
u32 VISIBLE32FLAT
pci_readl_32(u32 addr)
{
dprintf(3, "32: pci read : %x\n", addr);
return readl((void*)addr);
}
-#endif
u32 pci_readl(u32 addr)
{
if (MODESEGMENT) {
dprintf(3, "16: pci read : %x\n", addr);
- return call32(pci_readl_32, addr, -1);
+ extern void _cfunc32flat_pci_readl_32(u32 addr);
+ return call32(_cfunc32flat_pci_readl_32, addr, -1);
} else {
return pci_readl_32(addr);
}
u32 data;
};
-extern void pci_writel_32(struct reg32 *reg32);
-#if MODESEGMENT == 0
void VISIBLE32FLAT
pci_writel_32(struct reg32 *reg32)
{
dprintf(3, "32: pci write: %x, %x (%p)\n", reg32->addr, reg32->data, reg32);
writel((void*)(reg32->addr), reg32->data);
}
-#endif
void pci_writel(u32 addr, u32 val)
{
dprintf(3, "16: pci write: %x, %x (%x:%p)\n",
reg32.addr, reg32.data, GET_SEG(SS), ®32);
void *flatptr = MAKE_FLATPTR(GET_SEG(SS), ®32);
- call32(pci_writel_32, (u32)flatptr, -1);
+ extern void _cfunc32flat_pci_writel_32(struct reg32 *reg32);
+ call32(_cfunc32flat_pci_writel_32, (u32)flatptr, -1);
} else {
pci_writel_32(®32);
}
asm volatile(
"movw %w1, %%ss\n"
"movl %0, %%esp\n"
- "movl $s3_resume, %%edx\n"
+ "movl $_cfunc32flat_s3_resume, %%edx\n"
"jmp transition32\n"
: : "i"(BUILD_S3RESUME_STACK_ADDR), "r"(0)
);
jnz 1f
// Normal entry point
- ENTRY_INTO32 _start
+ ENTRY_INTO32 _cfunc32flat__start
// Entry point when a post call looks like a resume.
1:
pushl %cs // Move second descriptor after %cs to %gs
addl $16, (%esp)
popl %gs
- ENTRY_ARG_ESP handle_apm32
+ ENTRY_ARG_ESP _cfunc32seg_handle_apm32
popl %gs
popfl
lretl
pushl %gs // Backup %gs and set %gs=%ds
pushl %ds
popl %gs
- ENTRY_ARG_ESP handle_pcibios32
+ ENTRY_ARG_ESP _cfunc32seg_handle_pcibios32
popl %gs
popfl
lretl
movw %ax, %gs
movw %ax, %ss
movl $BUILD_STACK_ADDR, %esp
- ljmpl $SEG32_MODE32_CS, $_start
+ ljmpl $SEG32_MODE32_CS, $_cfunc32flat__start
.code16gcc
// int 18/19 are special - they reset stack and call into 32bit mode.
DECLFUNC entry_19
entry_19:
- ENTRY_INTO32 handle_19
+ ENTRY_INTO32 _cfunc32flat_handle_19
DECLFUNC entry_18
entry_18:
- ENTRY_INTO32 handle_18
+ ENTRY_INTO32 _cfunc32flat_handle_18
/****************************************************************
return 1;
}
-extern void yield_preempt(void);
-#if MODESEGMENT == 0
// Try to execute 32bit threads.
void VISIBLE32INIT
yield_preempt(void)
PreemptCount++;
switch_next(&MainThread);
}
-#endif
// 16bit code that checks if threads are pending and executes them if so.
void
|| GET_FLATPTR(MainThread.next) == &MainThread)
return;
- call32(yield_preempt, 0, 0);
+ extern void _cfunc32flat_yield_preempt(void);
+ call32(_cfunc32flat_yield_preempt, 0, 0);
}
// Notes a function as externally visible in the 16bit code chunk.
# define VISIBLE16 __VISIBLE
// Notes a function as externally visible in the 32bit flat code chunk.
-# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak
+# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline
// Notes a 32bit flat function that will only be called during init.
# define VISIBLE32INIT VISIBLE32FLAT
// Notes a function as externally visible in the 32bit segmented code chunk.
-# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak
+# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline
// Designate a variable as (only) visible to 16bit code.
# define VAR16 __section(".data16." UNIQSEC)
// Designate a variable as visible to 16bit, 32bit, and assembler code.
# define ASSERT32SEG() __force_link_error__only_in_32bit_segmented()
# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat()
#elif MODESEGMENT == 1
-# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak
-# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak
+# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline
+# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline
# define VISIBLE32INIT VISIBLE32FLAT
# define VISIBLE32SEG __VISIBLE
# define VAR16 __section(".discard.var16." UNIQSEC)
# define ASSERT32SEG() do { } while (0)
# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat()
#else
-# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak
+# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline
# define VISIBLE32FLAT __section(".text.runtime." UNIQSEC) __VISIBLE
# define VISIBLE32INIT __section(".text.init." UNIQSEC) __VISIBLE
-# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak
+# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline
# define VAR16 __section(".discard.var16." UNIQSEC)
# define VAR16VISIBLE VAR16 __VISIBLE __weak
# define VAR16EXPORT VAR16VISIBLE
for reloc in section.relocs:
symbol = reloc.symbol
if (symbol.section is None
- or symbol.section.fileid == section.fileid
- or symbol.name in xrefs):
+ or (symbol.section.fileid == section.fileid
+ and symbol.name == reloc.symbolname)
+ or reloc.symbolname in xrefs):
continue
- xrefs[symbol.name] = 1
+ xrefs[reloc.symbolname] = 1
addr = symbol.section.finalloc + symbol.offset
if (section.fileid == '32flat'
and symbol.section.fileid in ('16', '32seg')):
addr += BUILD_BIOS_ADDR
- out += "%s = 0x%x ;\n" % (symbol.name, addr)
+ out += "%s = 0x%x ;\n" % (reloc.symbolname, addr)
return out
# Write LD script includes for the given sections using relative offsets
# Section garbage collection
######################################################################
+CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)]
+
# Find and keep the section associated with a symbol (if available).
-def keepsymbol(reloc, infos, pos):
- symbolname = reloc.symbol.name
+def keepsymbol(reloc, infos, pos, isxref):
+ symbolname = reloc.symbolname
+ mustbecfunc = 0
+ for symprefix, needpos in CFUNCPREFIX:
+ if symbolname.startswith(symprefix):
+ if needpos != pos:
+ return -1
+ symbolname = symbolname[len(symprefix):]
+ mustbecfunc = 1
+ break
symbol = infos[pos][1].get(symbolname)
if (symbol is None or symbol.section is None
or symbol.section.name.startswith('.discard.')):
return -1
+ isdestcfunc = (symbol.section.name.startswith('.text.')
+ and not symbol.section.name.startswith('.text.asm.'))
+ if ((mustbecfunc and not isdestcfunc)
+ or (not mustbecfunc and isdestcfunc and isxref)):
+ return -1
+
reloc.symbol = symbol
keepsection(symbol.section, infos, pos)
return 0
section.keep = 1
# Keep all sections that this section points to
for reloc in section.relocs:
- ret = keepsymbol(reloc, infos, pos)
+ ret = keepsymbol(reloc, infos, pos, 0)
if not ret:
continue
# Not in primary sections - it may be a cross 16/32 reference
- ret = keepsymbol(reloc, infos, (pos+1)%3)
+ ret = keepsymbol(reloc, infos, (pos+1)%3, 1)
if not ret:
continue
- ret = keepsymbol(reloc, infos, (pos+2)%3)
+ ret = keepsymbol(reloc, infos, (pos+2)%3, 1)
if not ret:
continue
name = size = alignment = fileid = relocs = None
finalloc = category = keep = None
class Reloc:
- offset = type = symbol = None
+ offset = type = symbolname = symbol = None
class Symbol:
name = offset = section = None
reloc = Reloc()
reloc.offset = int(off, 16)
reloc.type = type
+ reloc.symbolname = symbolname
reloc.symbol = symbols[symbolname]
relocsection.relocs.append(reloc)
except ValueError:
findInit(sections)
# Determine the final memory locations of each kept section.
- # locsX = [(addr, sectioninfo), ...]
doLayout(sections)
# Write out linker script files.