From a055fb525ddf2c646038603d6325f337ab9dceee Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Thu, 26 Nov 2015 21:18:24 +0900 Subject: [PATCH] sysfs sample --- kernel/ap.c | 137 ++++++++++++++++++++++++++++++++++++++++++ kernel/include/init.h | 1 + kernel/init.c | 6 ++ 3 files changed, 144 insertions(+) diff --git a/kernel/ap.c b/kernel/ap.c index 4ec8d78e..39acf866 100644 --- a/kernel/ap.c +++ b/kernel/ap.c @@ -89,3 +89,140 @@ void ap_init(void) kprintf("AP Booting: Done\n"); } +#include +#include +#include +#include + +static ssize_t +show_int(struct sysfs_ops *ops, void *instance, void *buf, size_t size) +{ + int *p = instance; + + return snprintf(buf, size, "%d\n", *p); +}/* show_int() */ + +struct sysfs_ops show_int_ops = { + .show = &show_int, +}; + +struct fake_cpu_info { + int online; +}; + +static struct fake_cpu_info *fake_cpu_infos = NULL; + +enum fake_cpu_info_member { + ONLINE, +}; + +struct fake_cpu_info_ops { + enum fake_cpu_info_member member; + struct sysfs_ops ops; +}; + +static ssize_t +show_fake_cpu_info(struct sysfs_ops *ops0, void *instance, void *buf, + size_t size) +{ + struct fake_cpu_info_ops *ops + = container_of(ops0, struct fake_cpu_info_ops, ops); + struct fake_cpu_info *info = instance; + ssize_t n; + + switch (ops->member) { + case ONLINE: + n = snprintf(buf, size, "%d\n", info->online); + break; + default: + n = -EINVAL; + break; + } + + if (n >= size) { + n = -ENOSPC; + } + + return n; +} /* show_fake_cpu_info() */ + +static ssize_t +store_fake_cpu_info(struct sysfs_ops *ops0, void *instance, void *buf, + size_t size) +{ + struct fake_cpu_info_ops *ops + = container_of(ops0, struct fake_cpu_info_ops, ops); + struct fake_cpu_info *info = instance; + ssize_t n; + + switch (ops->member) { + case ONLINE: + kprintf("NYI:store_fake_cpu_info(%p,%p,%p,%ld): " + "online %d --> \"%.*s\"\n", + ops0, instance, buf, size, info->online, + (int)size, buf); + n = size; + break; + default: + n = -EIO; + break; + } + + return n; +} /* store_fake_cpu_info() */ + +static struct fake_cpu_info_ops show_fci_online = { + .member = ONLINE, + .ops.show = &show_fake_cpu_info, + .ops.store = &store_fake_cpu_info, +}; + +void +cpu_sysfs_setup(void) +{ + int error; + int cpu; + sysfs_handle_t targeth; + struct fake_cpu_info *info; + + /* sample of simple variable **********************************/ + error = sysfs_createf(&show_int_ops, &num_processors, 0444, + "/sys/devices/system/cpu/num_processors"); + if (error) { + panic("cpu_sysfs_setup:sysfs_createf(num_processors) failed\n"); + } + + /* sample of more complex variable ****************************/ + /* setup table */ + info = kmalloc(sizeof(*info) * num_processors, IHK_MC_AP_CRITICAL); + for (cpu = 0; cpu < num_processors; ++cpu) { + info[cpu].online = 10+cpu; + } + fake_cpu_infos = info; + + /* setup sysfs tree */ + for (cpu = 0; cpu < num_processors; ++cpu) { + /* online */ + error = sysfs_createf(&show_fci_online.ops, + &fake_cpu_infos[cpu], 0644, + "/sys/devices/system/cpu/cpu%d/online", cpu); + if (error) { + panic("cpu_sysfs_setup:sysfs_createf failed\n"); + } + + /* link to cpu%d */ + error = sysfs_lookupf(&targeth, + "/sys/devices/system/cpu/cpu%d", cpu); + if (error) { + panic("cpu_sysfs_setup:sysfs_lookupf failed\n"); + } + + error = sysfs_symlinkf(targeth, "/sys/bus/cpu/devices/cpu%d", + cpu); + if (error) { + panic("cpu_sysfs_setup:sysfs_symlinkf failed\n"); + } + } + + return; +} /* cpu_sysfs_setup() */ diff --git a/kernel/include/init.h b/kernel/include/init.h index 858a96c4..31717f16 100644 --- a/kernel/include/init.h +++ b/kernel/include/init.h @@ -28,6 +28,7 @@ extern void init_host_syscall_channel(void); extern void init_host_syscall_channel2(void); extern void sched_init(void); extern void pc_ap_init(void); +extern void cpu_sysfs_setup(void); extern char *find_command_line(char *name); diff --git a/kernel/init.c b/kernel/init.c index 82cd6a61..1e651c0b 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -251,6 +251,11 @@ static void rest_init(void) sched_init(); } +static void populate_sysfs(void) +{ + cpu_sysfs_setup(); +} /* populate_sysfs() */ + int host_ikc_inited = 0; extern int num_processors; extern void zero_tsc(void); @@ -280,6 +285,7 @@ static void post_init(void) create_os_procfs_files(); sysfs_init(); + populate_sysfs(); } #ifdef DCFA_RUN extern void user_main();