aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-09-15 23:21:24 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-09-15 23:21:24 -0700
commit6aa0542126e53fe96e6c794d35b7e36cfc925a47 (patch)
tree687659ef2c2d48827b90768596a37aaafed938e3
parent2cb4b33e20b10b2fc4f2808f498879b3d5ac7efd (diff)
downloadlwip-6aa0542126e53fe96e6c794d35b7e36cfc925a47.tar.gz
lwip-6aa0542126e53fe96e6c794d35b7e36cfc925a47.tar.xz
lwip-6aa0542126e53fe96e6c794d35b7e36cfc925a47.zip
core: pxe: additional work on the lwip port
Additional work on the lwip port. With this code, we can get pretty far before having problems. This moves malloc into the core directory, mostly so we can guard the malloc stuff with semaphores. I suspect we're going to have to have at least stub semaphores available to the library, since other things are going to need to be made thread-safe, too. This checkin contains debugging printfs and considerable amounts of placeholder code, that needs to be fixed. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--.gitignore1
-rw-r--r--com32/include/linux/list.h16
-rw-r--r--com32/lib/Makefile10
-rw-r--r--core/Makefile1
-rw-r--r--core/elflink/load_env32.c21
-rw-r--r--core/extern.inc2
-rw-r--r--core/fs/pxe/isr.c1
-rw-r--r--core/fs/pxe/pxe.c12
-rw-r--r--core/init.inc5
-rw-r--r--core/lwip/src/core/mem.c5
-rw-r--r--core/lwip/src/include/ipv4/lwip/inet.h48
-rw-r--r--core/lwip/src/include/lwipopts.h8
-rw-r--r--core/lwip/src/netif/undiif.c56
-rw-r--r--core/malloc/free.c (renamed from com32/lib/free.c)54
-rw-r--r--core/malloc/malloc.c (renamed from com32/lib/malloc.c)193
-rw-r--r--core/malloc/malloc.h (renamed from com32/lib/malloc.h)3
-rw-r--r--core/malloc/realloc.c (renamed from com32/lib/realloc.c)5
-rw-r--r--core/malloc/stack.c (renamed from com32/lib/stack.c)0
-rw-r--r--core/pxeisr.inc2
-rw-r--r--core/thread/idle_thread.c2
-rw-r--r--core/thread/start_thread.c5
21 files changed, 260 insertions, 190 deletions
diff --git a/.gitignore b/.gitignore
index 9b746288..fb1859ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
*.rej
*.s
*.sec
+*.sym
*.sys
*_bin.c
*.dyn
diff --git a/com32/include/linux/list.h b/com32/include/linux/list.h
index 3b92e254..ccf90031 100644
--- a/com32/include/linux/list.h
+++ b/com32/include/linux/list.h
@@ -1,3 +1,7 @@
+/*
+ * THIS FILE IS GPL - NEEDS TO BE REPLACED
+ */
+
// This list structure implementation is adapted from the list implementation
// on the Linux kernel.
@@ -35,18 +39,6 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
list->prev = list;
}
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
/*
* Insert a new entry between two known consecutive entries.
*
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 672d6807..419f70c7 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -113,14 +113,14 @@ LIBCONSOLE_OBJS = \
syslinux/serial.o
LIBOTHER_OBJS = \
- atoi.o atol.o atoll.o calloc.o creat.o \
+ atoi.o atol.o atoll.o calloc.o creat.o \
ctypes.o errno.o fgetc.o fgets.o fopen.o fprintf.o fputc.o \
fclose.o putchar.o ungetc.o setjmp.o \
- fputs.o fread2.o fread.o free.o fwrite2.o fwrite.o getopt.o \
- lrand48.o malloc.o stack.o memccpy.o memchr.o memcmp.o \
+ fputs.o fread2.o fread.o fwrite2.o fwrite.o getopt.o \
+ lrand48.o memccpy.o memchr.o memcmp.o \
memcpy.o mempcpy.o memmem.o memmove.o memset.o memswap.o \
- perror.o printf.o puts.o qsort.o realloc.o seed48.o snprintf.o \
- sprintf.o srand48.o sscanf.o strcasecmp.o strcat.o \
+ perror.o printf.o puts.o qsort.o seed48.o snprintf.o \
+ sprintf.o srand48.o sscanf.o strcasecmp.o strcat.o \
strchr.o strcmp.o strcpy.o strdup.o strerror.o strlen.o \
strnlen.o \
strncasecmp.o strncat.o strncmp.o strncpy.o strndup.o \
diff --git a/core/Makefile b/core/Makefile
index 7ea31931..69fb4264 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -99,6 +99,7 @@ kwdhash.gen: keywords genhash.pl
> $(@:.elf=.map)
$(OBJDUMP) -h $@ > $(@:.elf=.sec)
$(PERL) lstadjust.pl $(@:.elf=.lsr) $(@:.elf=.sec) $(@:.elf=.lst)
+ $(NM) -n $@ | awk '{ print $$1 " " $$3; }' > $(@:.elf=.sym)
$(LIB): $(LIBOBJS)
rm -f $@
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 361baa78..7ce300d6 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -66,23 +66,28 @@ static void call_constr(void)
}
}
-/* note to self: do _*NOT*_ use static key word on this function */
-void load_env32(com32sys_t * regs)
+/*
+ * Initialize the mandatory part of the 32-bit environment
+ */
+void init_env32(com32sys_t *regs)
{
call_constr();
- char *cmdline;
- struct cli_command c1, c2, c3, *comm, *aux;
openconsole(&dev_rawcon_r, &dev_ansiserial_w);
- INIT_LIST_HEAD(&cli_history_head);
- printf("Calling initilization constructor procedures...\n");
printf("Starting 32 bit elf module subsystem...\n");
- init_module_subsystem(&core_module);
-
printf("Str table address: %d\n", core_module.str_table);
printf("Sym table address: %d\n", core_module.sym_table);
printf("Str table size: %d\n", core_module.strtable_size);
printf("Sym table size: %d\n", core_module.symtable_size);
+ init_module_subsystem(&core_module);
+};
+
+/* note to self: do _*NOT*_ use static key word on this function */
+void cli32(com32sys_t * regs)
+{
+ char *cmdline;
+ struct cli_command c1, c2, c3, *comm, *aux;
+ INIT_LIST_HEAD(&cli_history_head);
c1.command = (char *)malloc(sizeof(char) * 16);
c2.command = (char *)malloc(sizeof(char) * 16);
diff --git a/core/extern.inc b/core/extern.inc
index 0c127805..4a3e778b 100644
--- a/core/extern.inc
+++ b/core/extern.inc
@@ -13,7 +13,7 @@
extern hello
; elflink/load_env32.c
- extern load_env32
+ extern init_env32
; fs.c
extern fs_init, searchdir, getfssec, mangle_name, load_config
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index e92e731c..7f1d2ea9 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -23,6 +23,7 @@ static void pm_return(void)
if (now != last_jiffies) {
last_jiffies = now;
__thread_process_timeouts();
+ __need_schedule = true; /* Switch threads if more than one runnable */
}
if (pxe_irq_pending) {
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 56037075..3a3ce22b 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -4,8 +4,10 @@
#include <fs.h>
#include <minmax.h>
#include <sys/cpu.h>
+#include <netinet/in.h>
#include "pxe.h"
#include "thread.h"
+#include "lwip/api.h"
#define GPXE 1
@@ -1419,6 +1421,10 @@ static void udp_init(void)
/*
* Network-specific initialization
*/
+err_t undi_tcpip_start(struct ip_addr *ipaddr,
+ struct ip_addr *netmask,
+ struct ip_addr *gw);
+
static void network_init(void)
{
struct bootp_t *bp = (struct bootp_t *)trackbuf;
@@ -1476,7 +1482,13 @@ static void network_init(void)
if ((DHCPMagic & 1) == 0)
DHCPMagic = 0;
+#if 1 /* new stuff */
+ undi_tcpip_start((struct ip_addr *)&MyIP,
+ (struct ip_addr *)&net_mask,
+ (struct ip_addr *)&gate_way);
+#else
udp_init();
+#endif
}
/*
diff --git a/core/init.inc b/core/init.inc
index a3fe3041..87bf0b91 100644
--- a/core/init.inc
+++ b/core/init.inc
@@ -74,6 +74,11 @@ dosram_k equ (real_mode_seg+0x1000) >> 6 ; Minimum DOS memory (K)
enough_ram:
skip_checks:
+;
+; Initialize the rest of the 32-bit environment
+;
+ pm_call init_env32
+
section .data16
err_noram db 'It appears your computer has less than '
asciidec dosram_k
diff --git a/core/lwip/src/core/mem.c b/core/lwip/src/core/mem.c
index b5f13ab3..6f97182d 100644
--- a/core/lwip/src/core/mem.c
+++ b/core/lwip/src/core/mem.c
@@ -181,7 +181,8 @@ static struct mem *ram_end;
static struct mem *lfree;
/** concurrent access protection */
-static sys_sem_t mem_sem;
+DECLARE_INIT_SEMAPHORE(_mem_sem, 1);
+#define mem_sem (&_mem_sem)
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
@@ -279,7 +280,9 @@ mem_init(void)
ram_end->next = MEM_SIZE_ALIGNED;
ram_end->prev = MEM_SIZE_ALIGNED;
+#if 0
mem_sem = sys_sem_new(1);
+#endif
/* initialize the lowest-free pointer to the start of the heap */
lfree = (struct mem *)ram;
diff --git a/core/lwip/src/include/ipv4/lwip/inet.h b/core/lwip/src/include/ipv4/lwip/inet.h
index 7e801308..5fda8b14 100644
--- a/core/lwip/src/include/ipv4/lwip/inet.h
+++ b/core/lwip/src/include/ipv4/lwip/inet.h
@@ -50,49 +50,11 @@ u32_t inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *addr);
char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
-#ifdef htons
-#undef htons
-#endif /* htons */
-#ifdef htonl
-#undef htonl
-#endif /* htonl */
-#ifdef ntohs
-#undef ntohs
-#endif /* ntohs */
-#ifdef ntohl
-#undef ntohl
-#endif /* ntohl */
-
-#ifndef LWIP_PLATFORM_BYTESWAP
-#define LWIP_PLATFORM_BYTESWAP 0
-#endif
-
-#if BYTE_ORDER == BIG_ENDIAN
-#define htons(x) (x)
-#define ntohs(x) (x)
-#define htonl(x) (x)
-#define ntohl(x) (x)
-#else /* BYTE_ORDER != BIG_ENDIAN */
-#ifdef LWIP_PREFIX_BYTEORDER_FUNCS
-/* workaround for naming collisions on some platforms */
-#define htons lwip_htons
-#define ntohs lwip_ntohs
-#define htonl lwip_htonl
-#define ntohl lwip_ntohl
-#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */
-#if LWIP_PLATFORM_BYTESWAP
-#define htons(x) LWIP_PLATFORM_HTONS(x)
-#define ntohs(x) LWIP_PLATFORM_HTONS(x)
-#define htonl(x) LWIP_PLATFORM_HTONL(x)
-#define ntohl(x) LWIP_PLATFORM_HTONL(x)
-#else /* LWIP_PLATFORM_BYTESWAP */
-u16_t htons(u16_t x);
-u16_t ntohs(u16_t x);
-u32_t htonl(u32_t x);
-u32_t ntohl(u32_t x);
-#endif /* LWIP_PLATFORM_BYTESWAP */
-
-#endif /* BYTE_ORDER == BIG_ENDIAN */
+/* Byte order functions removed in favor of <netinet/in.h> */
+#define LWIP_PLATFORM_HTONS(x) htons(x)
+#define LWIP_PLATFORM_NTOHS(x) ntohs(x)
+#define LWIP_PLATFORM_HTONL(x) htonl(x)
+#define LWIP_PLATFORM_NTOHL(x) ntohl(x)
#ifdef __cplusplus
}
diff --git a/core/lwip/src/include/lwipopts.h b/core/lwip/src/include/lwipopts.h
index 8bb1a838..71f6d719 100644
--- a/core/lwip/src/include/lwipopts.h
+++ b/core/lwip/src/include/lwipopts.h
@@ -6,6 +6,10 @@
#define MEMP_SANITY_CHECK 1 /* XXX: for debugging */
#define MEM_USE_POOLS_TRY_BIGGER_POOL 1
+#define TCPIP_MBOX_SIZE 64
+#define TCPIP_THREAD_PRIO 0
+#define TCPIP_THREAD_STACKSIZE 16384
+
#define MEMP_NUM_TCP_PCB 64
#define MEMP_NUM_TCP_SEG 256
#define MEMP_NUM_REASSDATA 32
@@ -13,10 +17,14 @@
#define ARP_TABLE_SIZE 16
#define IP_REASS_MAX_PBUFS 32
+#define LWIP_NETIF_API 1
+
#define LWIP_DNS 1
#define DNS_MAX_SERVERS 4
#define TCP_WND 32768
#define TCP_MSS 4096
#define TCP_SND_BUF 4096
+#define LWIP_PLATFORM_BYTESWAP 1
+
#endif /* __LWIPOPTS_H__ */
diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c
index 1aa45ef6..5033eee9 100644
--- a/core/lwip/src/netif/undiif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -53,9 +53,12 @@
#include <lwip/snmp.h>
#include "netif/etharp.h"
#include "netif/ppp_oe.h"
+#include "lwip/netifapi.h"
+#include "lwip/tcpip.h"
-#include <syslinux/pxe_api.h>
+#include <inttypes.h>
#include <string.h>
+#include <syslinux/pxe_api.h>
int pxe_call(int, void *);
#define PKTBUF_SIZE 2048
@@ -64,7 +67,7 @@ int pxe_call(int, void *);
#define IFNAME0 'u'
#define IFNAME1 'n'
-static struct netif *undi_netif;
+static struct netif undi_netif;
/**
* In this function, the hardware should be initialized.
@@ -290,7 +293,7 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
- if (undi_netif->input(p, undi_netif)!=ERR_OK)
+ if (undi_netif.input(p, &undi_netif)!=ERR_OK)
{ LWIP_DEBUGF(NETIF_DEBUG, ("undiif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
@@ -316,18 +319,46 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
-err_t
+extern uint8_t pxe_irq_vector;
+extern void pxe_isr(void);
+
+/* XXX: move this somewhere sensible */
+static void install_irq_vector(uint8_t irq, void (*isr)(void))
+{
+ unsigned int vec;
+
+ if (irq < 8)
+ vec = irq + 0x08;
+ else if (irq < 16)
+ vec = (irq - 8) + 0x70;
+ else
+ return; /* ERROR */
+
+ *(uint32_t *)(vec << 2) = (uint32_t)isr;
+}
+
+static err_t
undiif_init(struct netif *netif)
{
- LWIP_ASSERT("netif != NULL", (netif != NULL));
+ static __lowmem t_PXENV_UNDI_GET_INFORMATION undi_info;
- undi_netif = netif;
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "undi";
#endif /* LWIP_NETIF_HOSTNAME */
+ pxe_call(PXENV_UNDI_GET_INFORMATION, &undi_info);
+
+ printf("UNDI: baseio %04x int %d MTU %d type %d\n",
+ undi_info.BaseIo, undi_info.IntNumber, undi_info.MaxTranUnit,
+ undi_info.HwType);
+
+ /* Install the interrupt vector */
+ pxe_irq_vector = undi_info.IntNumber;
+ install_irq_vector(pxe_irq_vector, pxe_isr);
+
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
@@ -350,3 +381,16 @@ undiif_init(struct netif *netif)
return ERR_OK;
}
+
+err_t undi_tcpip_start(struct ip_addr *ipaddr,
+ struct ip_addr *netmask,
+ struct ip_addr *gw)
+{
+ // Start the TCP/IP thread & init stuff
+ tcpip_init(NULL, NULL);
+
+ // This should be done *after* the threading system and receive thread
+ // have both been started.
+ return netifapi_netif_add(&undi_netif, ipaddr, netmask, gw, NULL,
+ undiif_init, ethernet_input);
+}
diff --git a/com32/lib/free.c b/core/malloc/free.c
index a91ad8ef..d6cf34bb 100644
--- a/com32/lib/free.c
+++ b/core/malloc/free.c
@@ -7,8 +7,8 @@
#include <stdlib.h>
#include "malloc.h"
-static struct free_arena_header *
- __free_block(struct free_arena_header *ah) {
+static struct free_arena_header *__free_block(struct free_arena_header *ah)
+{
struct free_arena_header *pah, *nah;
pah = ah->a.prev;
@@ -74,7 +74,9 @@ void free(void *ptr)
assert( ARENA_TYPE_GET(ah->a.attrs) == ARENA_TYPE_USED );
#endif
+ sem_down(&__malloc_semaphore, 0);
__free_block(ah);
+ sem_up(&__malloc_semaphore);
/* Here we could insert code to return memory to the system. */
}
@@ -90,7 +92,10 @@ void __inject_free_block(struct free_arena_header *ah)
size_t a_end = (size_t) ah + ARENA_SIZE_GET(ah->a.attrs);
size_t n_end;
- for (nah = __malloc_head.a.next; ARENA_TYPE_GET(nah->a.attrs) != ARENA_TYPE_HEAD;
+ sem_down(&__malloc_semaphore, 0);
+
+ for (nah = __malloc_head.a.next;
+ ARENA_TYPE_GET(nah->a.attrs) != ARENA_TYPE_HEAD;
nah = nah->a.next) {
n_end = (size_t) nah + ARENA_SIZE_GET(nah->a.attrs);
@@ -103,30 +108,39 @@ void __inject_free_block(struct free_arena_header *ah)
continue;
/* Otherwise we have some sort of overlap - reject this block */
- return;
+ nah = NULL;
+ break;
}
/* Now, nah should point to the successor block */
- ah->a.next = nah;
- ah->a.prev = nah->a.prev;
- nah->a.prev = ah;
- ah->a.prev->a.next = ah;
+ if (nah) {
+ ah->a.next = nah;
+ ah->a.prev = nah->a.prev;
+ nah->a.prev = ah;
+ ah->a.prev->a.next = ah;
- __free_block(ah);
+ __free_block(ah);
+ }
+
+ sem_up(&__malloc_semaphore);
}
void __free_tagged(void *tag) {
- struct free_arena_header *fp, *nfp;
-
- for (fp = __malloc_head.a.next, nfp = fp->a.next;
- ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
- fp = nfp, nfp = fp->a.next) {
-
- if (ARENA_TYPE_GET(fp->a.attrs) == ARENA_TYPE_USED &&
- fp->a.tag == tag) {
- // Free this block
- __free_block(fp);
- }
+ struct free_arena_header *fp, *nfp;
+
+ sem_down(&__malloc_semaphore, 0);
+
+ for (fp = __malloc_head.a.next, nfp = fp->a.next;
+ ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
+ fp = nfp, nfp = fp->a.next) {
+
+ if (ARENA_TYPE_GET(fp->a.attrs) == ARENA_TYPE_USED &&
+ fp->a.tag == tag) {
+ // Free this block
+ __free_block(fp);
}
+ }
+
+ sem_up(&__malloc_semaphore);
}
diff --git a/com32/lib/malloc.c b/core/malloc/malloc.c
index cd978293..408a5c8e 100644
--- a/com32/lib/malloc.c
+++ b/core/malloc/malloc.c
@@ -9,8 +9,10 @@
#include <string.h>
#include <com32.h>
#include <syslinux/memscan.h>
-#include "init.h"
#include "malloc.h"
+#include "thread.h"
+
+DECLARE_INIT_SEMAPHORE(__malloc_semaphore, 1);
/**
* The global tag used to label all the new allocations
@@ -148,123 +150,132 @@ static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
void *malloc(size_t size)
{
struct free_arena_header *fp;
+ void *p = NULL;
if (size == 0)
return NULL;
+ sem_down(&__malloc_semaphore, 0);
+
/* Add the obligatory arena header, and round up */
size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
- for ( fp = __malloc_head.next_free ; ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD ;
+ for ( fp = __malloc_head.next_free ;
+ ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD ;
fp = fp->next_free ) {
if ( ARENA_SIZE_GET(fp->a.attrs) >= size ) {
/* Found fit -- allocate out of this block */
- return __malloc_from_block(fp, size);
+ p = __malloc_from_block(fp, size);
}
}
- /* Nothing found... need to request a block from the kernel */
- return NULL; /* No kernel to get stuff from */
+ sem_up(&__malloc_semaphore);
+
+ return p; /* No kernel to get stuff from */
}
int posix_memalign(void **memptr, size_t alignment, size_t size)
{
- struct free_arena_header *fp, *nfp;
- uintptr_t align_mask, align_addr;
-
- if (size == 0 || memptr == NULL) {
- return EINVAL;
- }
-
- if ((alignment & (alignment - 1)) != 0)
- return EINVAL;
-
+ struct free_arena_header *fp, *nfp;
+ uintptr_t align_mask, align_addr;
+
+ if (size == 0 || memptr == NULL) {
+ return EINVAL;
+ }
+
+ if ((alignment & (alignment - 1)) != 0)
+ return EINVAL;
+
#if 0
- // POSIX says to refuse alignments smaller than sizeof(void*)
- if (alignment % sizeof(void*) != 0)
- return EINVAL;
+ // POSIX says to refuse alignments smaller than sizeof(void*)
+ if (alignment % sizeof(void*) != 0)
+ return EINVAL;
#endif
- // The arena allocator can't handle alignments smaller than this
- if (alignment < sizeof(struct arena_header)) {
- alignment = sizeof(struct arena_header);
+ // The arena allocator can't handle alignments smaller than this
+ if (alignment < sizeof(struct arena_header)) {
+ alignment = sizeof(struct arena_header);
+ }
+ align_mask = ~(uintptr_t)(alignment - 1);
+
+ // Round up and add the arena_header
+ size = (size + sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
+
+ sem_down(&__malloc_semaphore, 0);
+
+ *memptr = NULL;
+
+ for (fp = __malloc_head.next_free;
+ ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
+ fp = fp->next_free) {
+
+ if (ARENA_SIZE_GET(fp->a.attrs) <= size)
+ continue;
+
+ align_addr = (uintptr_t)fp;
+
+ // Ensure the alignment leaves some space before for the header
+ if (align_addr % alignment == 0) {
+ align_addr += alignment;
+ } else {
+ align_addr = (align_addr + alignment - 1) & align_mask;
}
- align_mask = ~(uintptr_t)(alignment - 1);
-
- // Round up
- size = (size + sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
-
- *memptr = NULL;
-
- for (fp = __malloc_head.next_free;
- ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
- fp = fp->next_free) {
-
-
- if (ARENA_SIZE_GET(fp->a.attrs) <= size)
- continue;
-
- align_addr = (uintptr_t)fp;
-
- // Ensure the alignment leaves some space before for the header
- if (align_addr % alignment == 0) {
- align_addr += alignment;
- } else {
- align_addr = (align_addr + alignment - 1) & align_mask;
- }
- if (align_addr - (uintptr_t)fp == 2*sizeof(struct arena_header))
- align_addr += alignment;
-
- // See if now we have enough space
- if (align_addr + size > (uintptr_t)fp + ARENA_SIZE_GET(fp->a.attrs))
- continue;
-
- // We have a winner...
- if (align_addr - (uintptr_t)fp > sizeof(struct arena_header)) {
- // We must split the block before the alignment point
- nfp = (struct free_arena_header*)(align_addr - sizeof(struct arena_header));
- ARENA_TYPE_SET(nfp->a.attrs, ARENA_TYPE_FREE);
- ARENA_SIZE_SET(nfp->a.attrs,
- ARENA_SIZE_GET(fp->a.attrs) - ((uintptr_t)nfp - (uintptr_t)fp));
- nfp->a.tag = NULL;
- nfp->a.prev = fp;
- nfp->a.next = fp->a.next;
- nfp->prev_free = fp;
- nfp->next_free = fp->next_free;
-
- nfp->a.next->a.prev = nfp;
- nfp->next_free->prev_free = nfp;
-
- ARENA_SIZE_SET(fp->a.attrs, (uintptr_t)nfp - (uintptr_t)fp);
-
- fp->a.next = nfp;
- fp->next_free = nfp;
-
- *memptr = __malloc_from_block(nfp, size + sizeof(struct arena_header));
- } else {
- *memptr = __malloc_from_block(fp, size + sizeof(struct arena_header));
- }
- break;
+ if (align_addr - (uintptr_t)fp == 2*sizeof(struct arena_header))
+ align_addr += alignment;
+
+ // See if now we have enough space
+ if (align_addr + size > (uintptr_t)fp + ARENA_SIZE_GET(fp->a.attrs))
+ continue;
+
+ // We have a winner...
+ if (align_addr - (uintptr_t)fp > sizeof(struct arena_header)) {
+ // We must split the block before the alignment point
+ nfp = (struct free_arena_header *)
+ (align_addr - sizeof(struct arena_header));
+ ARENA_TYPE_SET(nfp->a.attrs, ARENA_TYPE_FREE);
+ ARENA_SIZE_SET(nfp->a.attrs, ARENA_SIZE_GET(fp->a.attrs)
+ - ((uintptr_t)nfp - (uintptr_t)fp));
+ nfp->a.tag = NULL;
+ nfp->a.prev = fp;
+ nfp->a.next = fp->a.next;
+ nfp->prev_free = fp;
+ nfp->next_free = fp->next_free;
+
+ nfp->a.next->a.prev = nfp;
+ nfp->next_free->prev_free = nfp;
+
+ ARENA_SIZE_SET(fp->a.attrs, (uintptr_t)nfp - (uintptr_t)fp);
+
+ fp->a.next = nfp;
+ fp->next_free = nfp;
+
+ fp = nfp;
}
- if (*memptr == NULL)
- return ENOMEM;
-
- return 0;
+ *memptr = __malloc_from_block(fp, size + sizeof(struct arena_header));
+ break;
+ }
+
+ sem_up(&__malloc_semaphore);
+
+ if (*memptr == NULL)
+ return ENOMEM;
+
+ return 0;
}
malloc_tag_t __mem_get_tag(void *memptr) {
- if (memptr) {
- struct arena_header *ah = (struct arena_header *)memptr - 1;
- return ah->tag;
- } else {
- return NULL;
- }
+ if (memptr) {
+ struct arena_header *ah = (struct arena_header *)memptr - 1;
+ return ah->tag;
+ } else {
+ return NULL;
+ }
}
void __mem_set_tag(void *memptr, malloc_tag_t tag) {
- if (memptr) {
- struct arena_header *ah = (struct arena_header *)memptr - 1;
- ah->tag = tag;
- }
+ if (memptr) {
+ struct arena_header *ah = (struct arena_header *)memptr - 1;
+ ah->tag = tag;
+ }
}
diff --git a/com32/lib/malloc.h b/core/malloc/malloc.h
index 58c54974..770b2cff 100644
--- a/com32/lib/malloc.h
+++ b/core/malloc/malloc.h
@@ -6,6 +6,9 @@
#include <stdint.h>
#include <stddef.h>
+#include "thread.h"
+
+extern struct semaphore __malloc_semaphore;
/*
* This is the minimum chunk size we will ask the kernel for; this should
diff --git a/com32/lib/realloc.c b/core/malloc/realloc.c
index 64fff72b..19f18747 100644
--- a/com32/lib/realloc.c
+++ b/core/malloc/realloc.c
@@ -22,6 +22,8 @@ void *realloc(void *ptr, size_t size)
return NULL;
}
+ sem_down(&__malloc_semaphore, 0);
+
ah = (struct free_arena_header *)
((struct arena_header *)ptr - 1);
@@ -34,6 +36,7 @@ void *realloc(void *ptr, size_t size)
if (oldsize >= newsize && newsize >= (oldsize >> 2) &&
oldsize - newsize < 4096) {
/* This allocation is close enough already. */
+ sem_up(&__malloc_semaphore);
return ptr;
} else {
xsize = oldsize;
@@ -85,9 +88,11 @@ void *realloc(void *ptr, size_t size)
}
}
/* otherwise, use up the whole block */
+ sem_up(&__malloc_semaphore);
return ptr;
} else {
/* Last resort: need to allocate a new block and copy */
+ sem_up(&__malloc_semaphore);
oldsize -= sizeof(struct arena_header);
newptr = malloc(size);
if (newptr) {
diff --git a/com32/lib/stack.c b/core/malloc/stack.c
index f1c9ea2b..f1c9ea2b 100644
--- a/com32/lib/stack.c
+++ b/core/malloc/stack.c
diff --git a/core/pxeisr.inc b/core/pxeisr.inc
index 1b5dc4d6..1c3e90a9 100644
--- a/core/pxeisr.inc
+++ b/core/pxeisr.inc
@@ -80,7 +80,7 @@ pxenv_undi_isr_buf:
.pkttype: resb 1
.size equ $-pxenv_undi_isr_buf
- global pxe_irq_num
+ global pxe_irq_vector
pxe_irq_vector resb 1 ; PXE IRQ vector
global pxe_irq_pending
pxe_irq_pending resb 1 ; IRQ pending flag
diff --git a/core/thread/idle_thread.c b/core/thread/idle_thread.c
index c5db9f4a..b51a4627 100644
--- a/core/thread/idle_thread.c
+++ b/core/thread/idle_thread.c
@@ -15,6 +15,6 @@ static void idle_thread_func(void *dummy)
void start_idle_thread(void)
{
- start_thread("idle", 4096, INT_MAX, idle_thread_func, NULL);
+ start_thread("idle", 4096, INT_MAX, idle_thread_func, NULL);
}
diff --git a/core/thread/start_thread.c b/core/thread/start_thread.c
index 5486e562..df08a9a5 100644
--- a/core/thread/start_thread.c
+++ b/core/thread/start_thread.c
@@ -1,5 +1,6 @@
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
#include "thread.h"
extern void __start_thread(void);
@@ -28,7 +29,7 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
return NULL;
t = (struct thread *)stack;
- stack = (char *)(t + 1); /* After the thread structure */
+ stack += sizeof(struct thread);
memset(t, 0, sizeof *t);
@@ -36,6 +37,8 @@ struct thread *start_thread(const char *name, size_t stack_size, int prio,
sp = (struct thread_stack *)(stack + stack_size) - 1;
t->esp = sp;
+ printf("Thread: %s @ %p, stack %p esp %p\n", name, t, stack, sp);
+
sp->errno = 0;
sp->esi = (size_t)start_func;
sp->edi = (size_t)func_arg;