diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile index f55080e..2c52ec5 100644 --- a/src/userland/loader/Makefile +++ b/src/userland/loader/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/loader: $(OBJS) +../../../initrd/loader: $(OBJS) ../../../build/hlib.o @echo "linking user program loader" @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile index f55080e..2c52ec5 100644 --- a/src/userland/loader/Makefile +++ b/src/userland/loader/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/loader: $(OBJS) +../../../initrd/loader: $(OBJS) ../../../build/hlib.o @echo "linking user program loader" @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c index 422d034..61e3989 100644 --- a/src/userland/loader/main.c +++ b/src/userland/loader/main.c @@ -6,5 +6,6 @@ log("hello world"); log("honey os is alive :)"); loadFromInitrd("pic"); + loadFromInitrd("keyboard"); return 0; } diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile index f55080e..2c52ec5 100644 --- a/src/userland/loader/Makefile +++ b/src/userland/loader/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/loader: $(OBJS) +../../../initrd/loader: $(OBJS) ../../../build/hlib.o @echo "linking user program loader" @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c index 422d034..61e3989 100644 --- a/src/userland/loader/main.c +++ b/src/userland/loader/main.c @@ -6,5 +6,6 @@ log("hello world"); log("honey os is alive :)"); loadFromInitrd("pic"); + loadFromInitrd("keyboard"); return 0; } diff --git a/src/userland/log/Makefile b/src/userland/log/Makefile index 749b70a..fb17fcb 100644 --- a/src/userland/log/Makefile +++ b/src/userland/log/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/log: $(OBJS) +../../../initrd/log: $(OBJS) ../../../build/hlib.o @echo "linking user program log" @$(LD) $(LD_FLAGS) -o ../../../initrd/log $(OBJS) diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile index f55080e..2c52ec5 100644 --- a/src/userland/loader/Makefile +++ b/src/userland/loader/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/loader: $(OBJS) +../../../initrd/loader: $(OBJS) ../../../build/hlib.o @echo "linking user program loader" @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c index 422d034..61e3989 100644 --- a/src/userland/loader/main.c +++ b/src/userland/loader/main.c @@ -6,5 +6,6 @@ log("hello world"); log("honey os is alive :)"); loadFromInitrd("pic"); + loadFromInitrd("keyboard"); return 0; } diff --git a/src/userland/log/Makefile b/src/userland/log/Makefile index 749b70a..fb17fcb 100644 --- a/src/userland/log/Makefile +++ b/src/userland/log/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/log: $(OBJS) +../../../initrd/log: $(OBJS) ../../../build/hlib.o @echo "linking user program log" @$(LD) $(LD_FLAGS) -o ../../../initrd/log $(OBJS) diff --git a/src/userland/pic/Makefile b/src/userland/pic/Makefile index 2f7a767..573d46d 100644 --- a/src/userland/pic/Makefile +++ b/src/userland/pic/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/pic: $(OBJS) +../../../initrd/pic: $(OBJS) ../../../build/hlib.o @echo "linking user program 8259 PIC" @$(LD) $(LD_FLAGS) -o ../../../initrd/pic $(OBJS) diff --git a/compile_flags.txt b/compile_flags.txt index 9e33535..3b47433 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,3 +4,4 @@ -Wno-microsoft-anon-tag -Wno-incompatible-library-redeclaration -I./src/kernel/include +-I./src/userland/hlib/include diff --git a/src/include/hlib.h b/src/include/hlib.h index c7c8b2d..76cffc8 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -15,5 +15,14 @@ extern void log(char *); extern void subscribeInterrupt(uint32_t intNo, void *handler); extern void loadFromInitrd(char *name); +extern uint32_t createEvent(char *name); +extern uint32_t syscall(uint32_t function, uint32_t parameter0, + uint32_t parameter1, uint32_t parameter2, + uint32_t parameter3); +extern void fireEvent(uint32_t eventId); +extern void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)); +extern uint32_t getEvent(uint32_t service, char *name); +extern uint32_t getService(char *name); #endif diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 0006b10..5447f13 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -9,6 +9,7 @@ PagingInfo pagingInfo; char *name; ListElement *providers; + ListElement *events; } Service; // the name is subject to change @@ -18,6 +19,11 @@ Service *service; } Provider; +typedef struct { + char *name; + ListElement *subscriptions; +} Event; + extern Service *loadElf(void *fileData, char *serviceName); extern void resume(Syscall *syscall); diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 959c87b..a60440e 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -32,4 +32,6 @@ extern void listAdd(ListElement **list, void *data); extern void *listPopFirst(ListElement **list); +extern uint32_t listCount(ListElement *list); + #endif diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index d992a2f..9b1cbc3 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -175,6 +175,52 @@ listAdd(&interruptSubscriptions[call->parameters[0]], provider); } +void handleCreateEventSyscall(Syscall *call) { + Event *event = malloc(sizeof(Provider)); + Service *service = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + service->pagingInfo.pageDirectory, PTR(call->parameters[0]))); + event->subscriptions = NULL; + event->name = name; + call->returnValue = listCount(service->events); + listAdd(&service->events, event); +} + +void handleGetEventSyscall(Syscall *call) { + uint32_t i = 0; + Service *callService = call->service; + char *name = kernelMapPhysical(getPhysicalAddress( + callService->pagingInfo.pageDirectory, PTR(call->parameters[1]))); + Service *service = listGet(services, call->parameters[0]); + foreach (service->events, Event *, event, { + if (stringEquals(event->name, name)) { + call->returnValue = i; + break; + } + i++; + }) + ; + unmapPage(name); +} + +void handleFireEventSyscall(Syscall *call) { + Service *service = call->service; + Event *event = listGet(service->events, call->parameters[0]); + foreach (event->subscriptions, Provider *, provider, + { scheduleProvider(provider, 0, 0, 0); }) + ; +} + +void handleSubscribeEventSyscall(Syscall *call) { + Service *eventService = listGet(services, call->parameters[0]); + Event *event = listGet(eventService->events, call->parameters[1]); + Provider *provider = malloc(sizeof(Provider)); + provider->name = "event subscription"; + provider->service = call->service; + provider->address = PTR(call->parameters[2]); + listAdd(&event->subscriptions, provider); +} + void (*syscallHandlers[])(Syscall *) = { 0, (void *)handleInstallSyscall, @@ -185,4 +231,8 @@ (void *)handleGetServiceSyscall, (void *)handleGetProviderSyscall, (void *)handleSubscribeInterruptSyscall, + (void *)handleCreateEventSyscall, + (void *)handleGetEventSyscall, + (void *)handleFireEventSyscall, + (void *)handleSubscribeEventSyscall, }; diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c index fca8497..e13ba57 100644 --- a/src/kernel/util/list.c +++ b/src/kernel/util/list.c @@ -26,3 +26,10 @@ free(resultElement); return result; } + +uint32_t listCount(ListElement *list) { + uint32_t i = 0; + foreach (list, void *, element, { i++; }) + ; + return i; +} diff --git a/src/userland/hlib/Makefile b/src/userland/hlib/Makefile index 0bc3580..4870f51 100644 --- a/src/userland/hlib/Makefile +++ b/src/userland/hlib/Makefile @@ -1,19 +1,19 @@ CC = i686-elf-gcc CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 LD = i686-elf-ld -LD_FLAGS = -z max-page-size=0x1000 -e main +LD_FLAGS = -z max-page-size=0x1000 AS = nasm ASFlAGS = -felf32 BUILD_FOLDER = build -SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +SOURCE_FILES := $(shell find . -name "*.c" -or -name "*.asm") OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) ../../../initrd/hlib: $(OBJS) @echo "linking the honey OS c libary" @$(LD) $(LD_FLAGS) -o ../../../build/hlib.o $(OBJS) -T link.ld -r - @$(LD) $(LD_FLAGS) -o ../../../initrd/hlib $(OBJS) -T link.ld + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) -T link.ld $(BUILD_FOLDER)/%.asm.o: %.asm @echo "asembling $<" diff --git a/src/userland/hlib/events/events.c b/src/userland/hlib/events/events.c new file mode 100644 index 0000000..4e5a1e3 --- /dev/null +++ b/src/userland/hlib/events/events.c @@ -0,0 +1,20 @@ +#include +#include +#include + +uint32_t createEvent(char *name) { + return syscall(SYS_CREATE_EVENT, U32(name), 0, 0, 0); +} + +uint32_t getEvent(uint32_t service, char *name) { + return syscall(SYS_GET_EVENT, service, U32(name), 0, 0); +} + +void fireEvent(uint32_t eventNumber) { + syscall(SYS_FIRE_EVENT, eventNumber, 0, 0, 0); +} + +void subscribeEvent(uint32_t service, uint32_t event, + void(handler)(void *, uint32_t)) { + syscall(SYS_SUBSCRIBE_EVENT, service, event, U32(handler), 0); +} diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index a0764de..8f618db 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -14,6 +14,10 @@ SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, SYS_SUBSCRIBE_INTERRUPT = 8, + SYS_CREATE_EVENT = 9, + SYS_GET_EVENT = 10, + SYS_FIRE_EVENT = 11, + SYS_SUBSCRIBE_EVENT = 12, } SyscallIds; #endif diff --git a/src/userland/hlib/main.c b/src/userland/hlib/main.c index 1404907..96b8645 100644 --- a/src/userland/hlib/main.c +++ b/src/userland/hlib/main.c @@ -41,7 +41,7 @@ return size; } -uint32_t getModule(char *name) { +uint32_t getService(char *name) { return syscall(SYS_GET_SERVICE, U32(name), strlen(name), 0, 0); } @@ -57,7 +57,7 @@ void log(char *message) { if (logModule == 0) { - logModule = getModule("log"); + logModule = getService("log"); logProvider = getProvider(logModule, "log"); } request(logModule, logProvider, message, strlen(message)); diff --git a/src/userland/keyboard/Makefile b/src/userland/keyboard/Makefile new file mode 100644 index 0000000..99ace25 --- /dev/null +++ b/src/userland/keyboard/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 -T ../link.ld +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/keyboard: $(OBJS) ../../../build/hlib.o + @echo "linking user program PS/2 keyboard" + @$(LD) $(LD_FLAGS) -o $@ $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/keyboard/main.c b/src/userland/keyboard/main.c new file mode 100644 index 0000000..50b548c --- /dev/null +++ b/src/userland/keyboard/main.c @@ -0,0 +1,14 @@ +#include +#include + +void onKey(void *data, uint32_t dataSize) { + uint32_t keyCode = ioIn(0x60, 1); + log("key!"); +} + +int32_t main() { + log("keyboard handler installed"); + uint32_t service = getService("pic"); + uint32_t event = getEvent(service, "irq1"); + subscribeEvent(service, event, onKey); +} diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile index f55080e..2c52ec5 100644 --- a/src/userland/loader/Makefile +++ b/src/userland/loader/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/loader: $(OBJS) +../../../initrd/loader: $(OBJS) ../../../build/hlib.o @echo "linking user program loader" @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c index 422d034..61e3989 100644 --- a/src/userland/loader/main.c +++ b/src/userland/loader/main.c @@ -6,5 +6,6 @@ log("hello world"); log("honey os is alive :)"); loadFromInitrd("pic"); + loadFromInitrd("keyboard"); return 0; } diff --git a/src/userland/log/Makefile b/src/userland/log/Makefile index 749b70a..fb17fcb 100644 --- a/src/userland/log/Makefile +++ b/src/userland/log/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/log: $(OBJS) +../../../initrd/log: $(OBJS) ../../../build/hlib.o @echo "linking user program log" @$(LD) $(LD_FLAGS) -o ../../../initrd/log $(OBJS) diff --git a/src/userland/pic/Makefile b/src/userland/pic/Makefile index 2f7a767..573d46d 100644 --- a/src/userland/pic/Makefile +++ b/src/userland/pic/Makefile @@ -10,7 +10,7 @@ SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) -../../../initrd/pic: $(OBJS) +../../../initrd/pic: $(OBJS) ../../../build/hlib.o @echo "linking user program 8259 PIC" @$(LD) $(LD_FLAGS) -o ../../../initrd/pic $(OBJS) diff --git a/src/userland/pic/main.c b/src/userland/pic/main.c index cf62164..db6c0b7 100644 --- a/src/userland/pic/main.c +++ b/src/userland/pic/main.c @@ -5,18 +5,12 @@ #define PIC1 0x20 #define PIC2 0xA0 -#define COMMAND_ICW4 0x01 -#define COMMAND_SINGLE 0x02 -#define COMMAND_INTERVAL4 0x04 -#define COMMAND_LEVEL 0x08 -#define COMMAND_INIT 0x10 -#define DATA(x) PIC##x + 1 +char *eventNames[] = { + "irq0", "irq1", "irq2", "irq3", "irq4", "irq5", "irq6", "irq7", + "irq8", "irq9", "irq10", "irq11", "irq12", "irq13", "irq14", "irq15", +}; -#define COMMAND(x, command) ioOut(1, PIC##x, command); - -#define BOTH(command, ...) \ - command(1, __VA_ARGS__); \ - command(2, __VA_ARGS__); +uint32_t eventIds[16]; #define PIC_READ_IRR 0x0A uint16_t getIRR() { @@ -46,27 +40,20 @@ sentPic2EOI = true; ioOut(PIC2, 0x20, 1); } - if (i == 1) { - ioIn(0x60, 1); - log("keyboard!"); - } + fireEvent(eventIds[i]); } } -uint32_t x = 1; - -void loop() { - while (x > 0) - ; -} - int32_t main() { log("setting up interrupt handlers for the PIC"); for (uint32_t i = 32; i < 48; i++) { subscribeInterrupt(i, irqMaster); } ioOut(0x21, 0x1, 1); - ioOut(0xA1, 0x1, 1); + ioOut(0xA1, 0x0, 1); ioOut(0x70, ioIn(0x70, 1) | 0x80, 1); ioIn(0x71, 1); + for (uint8_t i = 0; i < sizeof(eventNames) / sizeof(void *); i++) { + eventIds[i] = createEvent(eventNames[i]); + } }